Python?隊列Queue和PriorityQueue解析
Python 隊列Queue和PriorityQueue
Python的Queue模塊
適用于多線程編程的FIFO實現(xiàn)。它可用于在生產(chǎn)者(producer)和消費者(consumer)之間線程安全(thread-safe)地傳遞消息或其它數(shù)據(jù),因此多個線程可以共用同一個Queue實例。
- FIFO: First in, First out.先進先出
- LIFO: Last in, First out.后進先出
優(yōu)先級隊列PriorityQueue的特點
- 給定一個優(yōu)先級(Priority)
- 每次pop操作都會返回一個擁有最高優(yōu)先級的項
from queue import Queue#先進先出隊列 from queue import PriorityQueue#優(yōu)先級隊列 import time #隊列:先進先出 q = Queue()#創(chuàng)建一個空隊列,隊列大小沒有指定 #判斷隊列是是否為空 #當一個隊列為空的時候如果再用get取則會堵塞,所以取隊列的時候一般是用到 #get_nowait()方法,這種方法在向一個空隊列取值的時候會拋一個Empty異常 #所以更常用的方法是先判斷一個隊列是否為空,如果不為空則取值 ? ? print(q.empty()) #隊列的操作:存--put() ?取--get() q.put('page1') q.put('page2') q.put('page3') ? print(q.empty()) #判斷隊列是否已經(jīng)滿了 print(q.full()) ? q1 = Queue(3)#在創(chuàng)建隊列時,指定隊列大?。ū硎驹撽犃凶疃嗄艽娑嗌賯€元素) q1.put('1') q1.put('1') q1.put('1') print(q1.full()) ? ? q2 = Queue(3) q2.put('1') q2.put('2') q2.put('3') value = q2.get()#遵循的原則是:先進先出 print(value) print(q2.full()) ? #存數(shù)據(jù)---阻塞 q3 = Queue(3) q3.put(1) q3.put(2) q3.put(3) # q3.put(4)#如果隊列已經(jīng)滿了,等著(阻塞),一直等到隊列騰出空間,然后把值存入到隊列當中。 ? #取數(shù)據(jù)--阻塞 q4 = Queue(3) q4.put(1) value = q4.get()#1,此時隊列為空 print('q4:',value) # value = q4.get()#阻塞,直到隊列當中有新值的時候,取出,結(jié)束阻塞。 ? #非阻塞 q5 = Queue(3) q5.put(1) ? #1.取 print('q5.qsize:',q5.qsize())#當前隊列當中的元素個數(shù) #方法1: # while not q5.empty(): # ? ? value2 = q5.get(block=False)#block為Ture,表示阻塞,否則為非阻塞。非阻塞就是“強取” # ? ? print('q5:',value2) #方法2: while q5.qsize()>0: ? ? value2 = q5.get(block=False) ? ? print('q5:',value2) ? print('q5.qsize:',q5.qsize()) #存 q6 = Queue(3) ? #方法1: # print(q6.maxsize)#得到隊列最大容量 # i = 0 # while i<q6.maxsize: # ? ? q6.put(i) # ? ? i+=1 ? #方法2: while not q6.full(): ? ? q6.put(1,block=False)#非阻塞 ? ? '''------------------------------其它的屬性和方法-----------------------------''' q7 = Queue(3) # q7.get(block=False) print(time.time()) try: ? ? q7.get(timeout=2)#阻塞時長 except: ? ? pass print(time.time()) ? q8 = Queue(3) # q8.get_nowait()#強取 ? '''------------------------------優(yōu)先級隊列-----------------------------''' q = PriorityQueue() ? # 格式:q.put((數(shù)字,值)) #特點:數(shù)字越小,優(yōu)先級越高 q.put((1,'lori')) q.put((-1,'Jseon')) q.put((10,'King')) ? i = 0 while i<q.qsize(): ? ? print(q.get())
python 實現(xiàn)一個優(yōu)先級隊列
import heapq ? class PriorityQueue(object): ? ? def __init__(self): ? ? ? ? self._queue = [] ? ? ? ?#創(chuàng)建一個空列表用于存放隊列 ? ? ? ? self._index = 0 ? ? ? ?#指針用于記錄push的次序 ? ?? ? ? def push(self, item, priority): ? ? ? ? """隊列由(priority, index, item)形式的元祖構成""" ? ? ? ? heapq.heappush(self._queue, (-priority, self._index, item))? ? ? ? ? self._index += 1 ? ? ? ?? ? ? def pop(self): ? ? ? ? return heapq.heappop(self._queue)[-1] ? ?#返回擁有最高優(yōu)先級的項 ? class Item(object): ? ? def __init__(self, name): ? ? ? ? self.name = name ? ? ? def __repr__(self): ? ? ? ? return 'Item: {!r}'.format(self.name) ? if __name__ == '__main__': ? ? q = PriorityQueue() ? ? q.push(Item('foo'), 5) ? ? q.push(Item('bar'), 1) ? ? q.push(Item('spam'), 3) ? ? q.push(Item('grok'), 1) ? ? for i in range(4): ? ? ? ? print(q._queue) ? ? ? ? print(q.pop())
對隊列進行4次pop()操作,打印結(jié)果如下:
[(-5, 0, Item: 'foo'), (-1, 1, Item: 'bar'), (-3, 2, Item: 'spam'), (-1, 3, Item: 'grok')]
Item: 'foo'
[(-3, 2, Item: 'spam'), (-1, 1, Item: 'bar'), (-1, 3, Item: 'grok')]
Item: 'spam'
[(-1, 1, Item: 'bar'), (-1, 3, Item: 'grok')]
Item: 'bar'
[(-1, 3, Item: 'grok')]
Item: 'grok'
可以觀察出pop()是如何返回一個擁有最高優(yōu)先級的項。對于擁有相同優(yōu)先級的項(bar和grok),會按照被插入隊列的順序來返回。
代碼的核心是利用heapq模塊,之前已經(jīng)說過,heapq.heappop()會返回最小值項,因此需要把 priority 的值變?yōu)樨?,才能讓隊列將每一項按從最高到最低?yōu)先級的順序級來排序。
python 優(yōu)先隊列PriorityQueue
普通的隊列是一種先進先出的數(shù)據(jù)結(jié)構,元素在隊列尾追加,而從隊列頭刪除。在優(yōu)先隊列中,元素被賦予優(yōu)先級。
當訪問元素時,具有最高優(yōu)先級的元素最先刪除。優(yōu)先隊列具有最高級先出的行為特征。通常采用堆數(shù)據(jù)結(jié)構來實現(xiàn)。
我們可以利用優(yōu)先隊列中元素被賦予優(yōu)先級的這個特點來保存到當前狀態(tài)下的若干個最大的元素值,這樣優(yōu)先級越高那么元素就可以先被處理,PriorityQueue屬于queue模塊中的一個類,其中經(jīng)常使用到的有三個方法:聲明一個優(yōu)先隊列、往優(yōu)先隊列中加入元素、往優(yōu)先隊列中移除元素
- ① 聲明一個優(yōu)先隊列:queue.PriorityQueue()
- ② 往隊列中加入元素:queue.put(self, item, block=True, timeout=None)
- ③ 往隊列中刪除元素:queue.get(self, block=True, timeout=None)
在往隊列中加入元素的時候第一個元素值表示的是元素的優(yōu)先級,并且值越小那么優(yōu)先級越高,所以隊首元素的優(yōu)先級是最高的,而且經(jīng)常加入隊列的元素類型為元組這樣就可以在隊列中保存多個值,
下面是具體的例子
import queue if __name__ == '__main__': queue = queue.PriorityQueue() queue.put((100, 100)) queue.put((-12, -7)) queue.put((7, 8)) while not queue.empty(): print(queue.get())
輸出結(jié)果:
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
python 使用tkinter與messagebox寫界面和彈窗
這篇文章主要介紹了python 使用tkinter與messagebox寫界面和彈窗,文章內(nèi)容詳細,具有一的的參考價值,需要的小伙伴可以參考一下2022-03-03python wxpython 實現(xiàn)界面跳轉(zhuǎn)功能
wxpython沒提供界面跳轉(zhuǎn)的方式,所以就需要借助threading模塊,本文給大家分享python wxpython 實現(xiàn)界面跳轉(zhuǎn)功能,感興趣的朋友跟隨小編一起看看吧2019-12-12