Python?隊(duì)列Queue和PriorityQueue解析
Python 隊(duì)列Queue和PriorityQueue
Python的Queue模塊
適用于多線程編程的FIFO實(shí)現(xiàn)。它可用于在生產(chǎn)者(producer)和消費(fèi)者(consumer)之間線程安全(thread-safe)地傳遞消息或其它數(shù)據(jù),因此多個(gè)線程可以共用同一個(gè)Queue實(shí)例。
- FIFO: First in, First out.先進(jìn)先出
- LIFO: Last in, First out.后進(jìn)先出
優(yōu)先級(jí)隊(duì)列PriorityQueue的特點(diǎn)
- 給定一個(gè)優(yōu)先級(jí)(Priority)
- 每次pop操作都會(huì)返回一個(gè)擁有最高優(yōu)先級(jí)的項(xiàng)
from queue import Queue#先進(jìn)先出隊(duì)列
from queue import PriorityQueue#優(yōu)先級(jí)隊(duì)列
import time
#隊(duì)列:先進(jìn)先出
q = Queue()#創(chuàng)建一個(gè)空隊(duì)列,隊(duì)列大小沒有指定
#判斷隊(duì)列是是否為空
#當(dāng)一個(gè)隊(duì)列為空的時(shí)候如果再用get取則會(huì)堵塞,所以取隊(duì)列的時(shí)候一般是用到
#get_nowait()方法,這種方法在向一個(gè)空隊(duì)列取值的時(shí)候會(huì)拋一個(gè)Empty異常
#所以更常用的方法是先判斷一個(gè)隊(duì)列是否為空,如果不為空則取值
?
?
print(q.empty())
#隊(duì)列的操作:存--put() ?取--get()
q.put('page1')
q.put('page2')
q.put('page3')
?
print(q.empty())
#判斷隊(duì)列是否已經(jīng)滿了
print(q.full())
?
q1 = Queue(3)#在創(chuàng)建隊(duì)列時(shí),指定隊(duì)列大小(表示該隊(duì)列最多能存多少個(gè)元素)
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()#遵循的原則是:先進(jìn)先出
print(value)
print(q2.full())
?
#存數(shù)據(jù)---阻塞
q3 = Queue(3)
q3.put(1)
q3.put(2)
q3.put(3)
# q3.put(4)#如果隊(duì)列已經(jīng)滿了,等著(阻塞),一直等到隊(duì)列騰出空間,然后把值存入到隊(duì)列當(dāng)中。
?
#取數(shù)據(jù)--阻塞
q4 = Queue(3)
q4.put(1)
value = q4.get()#1,此時(shí)隊(duì)列為空
print('q4:',value)
# value = q4.get()#阻塞,直到隊(duì)列當(dāng)中有新值的時(shí)候,取出,結(jié)束阻塞。
?
#非阻塞
q5 = Queue(3)
q5.put(1)
?
#1.取
print('q5.qsize:',q5.qsize())#當(dāng)前隊(duì)列當(dāng)中的元素個(gè)數(shù)
#方法1:
# while not q5.empty():
# ? ? value2 = q5.get(block=False)#block為Ture,表示阻塞,否則為非阻塞。非阻塞就是“強(qiáng)取”
# ? ? 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)#得到隊(duì)列最大容量
# 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)#阻塞時(shí)長(zhǎng)
except:
? ? pass
print(time.time())
?
q8 = Queue(3)
# q8.get_nowait()#強(qiáng)取
?
'''------------------------------優(yōu)先級(jí)隊(duì)列-----------------------------'''
q = PriorityQueue()
?
# 格式:q.put((數(shù)字,值))
#特點(diǎn):數(shù)字越小,優(yōu)先級(jí)越高
q.put((1,'lori'))
q.put((-1,'Jseon'))
q.put((10,'King'))
?
i = 0
while i<q.qsize():
? ? print(q.get())python 實(shí)現(xiàn)一個(gè)優(yōu)先級(jí)隊(duì)列
import heapq
?
class PriorityQueue(object):
? ? def __init__(self):
? ? ? ? self._queue = [] ? ? ? ?#創(chuàng)建一個(gè)空列表用于存放隊(duì)列
? ? ? ? self._index = 0 ? ? ? ?#指針用于記錄push的次序
? ??
? ? def push(self, item, priority):
? ? ? ? """隊(duì)列由(priority, index, item)形式的元祖構(gòu)成"""
? ? ? ? heapq.heappush(self._queue, (-priority, self._index, item))?
? ? ? ? self._index += 1
? ? ? ??
? ? def pop(self):
? ? ? ? return heapq.heappop(self._queue)[-1] ? ?#返回?fù)碛凶罡邇?yōu)先級(jí)的項(xiàng)
?
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())對(duì)隊(duì)列進(jìn)行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()是如何返回一個(gè)擁有最高優(yōu)先級(jí)的項(xiàng)。對(duì)于擁有相同優(yōu)先級(jí)的項(xiàng)(bar和grok),會(huì)按照被插入隊(duì)列的順序來返回。
代碼的核心是利用heapq模塊,之前已經(jīng)說過,heapq.heappop()會(huì)返回最小值項(xiàng),因此需要把 priority 的值變?yōu)樨?fù),才能讓隊(duì)列將每一項(xiàng)按從最高到最低優(yōu)先級(jí)的順序級(jí)來排序。
python 優(yōu)先隊(duì)列PriorityQueue
普通的隊(duì)列是一種先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),元素在隊(duì)列尾追加,而從隊(duì)列頭刪除。在優(yōu)先隊(duì)列中,元素被賦予優(yōu)先級(jí)。
當(dāng)訪問元素時(shí),具有最高優(yōu)先級(jí)的元素最先刪除。優(yōu)先隊(duì)列具有最高級(jí)先出的行為特征。通常采用堆數(shù)據(jù)結(jié)構(gòu)來實(shí)現(xiàn)。
我們可以利用優(yōu)先隊(duì)列中元素被賦予優(yōu)先級(jí)的這個(gè)特點(diǎn)來保存到當(dāng)前狀態(tài)下的若干個(gè)最大的元素值,這樣優(yōu)先級(jí)越高那么元素就可以先被處理,PriorityQueue屬于queue模塊中的一個(gè)類,其中經(jīng)常使用到的有三個(gè)方法:聲明一個(gè)優(yōu)先隊(duì)列、往優(yōu)先隊(duì)列中加入元素、往優(yōu)先隊(duì)列中移除元素
- ① 聲明一個(gè)優(yōu)先隊(duì)列:queue.PriorityQueue()
- ② 往隊(duì)列中加入元素:queue.put(self, item, block=True, timeout=None)
- ③ 往隊(duì)列中刪除元素:queue.get(self, block=True, timeout=None)
在往隊(duì)列中加入元素的時(shí)候第一個(gè)元素值表示的是元素的優(yōu)先級(jí),并且值越小那么優(yōu)先級(jí)越高,所以隊(duì)首元素的優(yōu)先級(jí)是最高的,而且經(jīng)常加入隊(duì)列的元素類型為元組這樣就可以在隊(duì)列中保存多個(gè)值,
下面是具體的例子
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é)果:

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python實(shí)現(xiàn)PDF轉(zhuǎn)換文本詳解
這篇文章主要介紹了詳解用Python把PDF轉(zhuǎn)換為文本方法總結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-10-10
django使用sqlite3統(tǒng)計(jì)前臺(tái)站點(diǎn)訪問數(shù)量示例
這篇文章主要為大家介紹了django使用sqlite3統(tǒng)計(jì)前臺(tái)站點(diǎn)訪問數(shù)量示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
Python對(duì)象的底層實(shí)現(xiàn)源碼學(xué)習(xí)
這篇文章主要為大家介紹了Python對(duì)象的底層實(shí)現(xiàn)源碼學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
Python調(diào)用C++,通過Pybind11制作Python接口
今天小編就為大家分享一篇關(guān)于Python調(diào)用C++,通過Pybind11制作Python接口,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-10-10
python實(shí)現(xiàn)12306火車票查詢器
這篇文章主要介紹了python實(shí)現(xiàn)12306火車票查詢器,需要的朋友可以參考下2017-04-04
Python?實(shí)現(xiàn)簡(jiǎn)單智能聊天機(jī)器人
這篇文章主要介紹了Python?實(shí)現(xiàn)簡(jiǎn)單智能聊天機(jī)器人,首先通過計(jì)算機(jī)接收用戶的語音輸入再將用戶輸入的語音輸入轉(zhuǎn)化為文本信息展開實(shí)現(xiàn)過程,需要的小伙伴可以參考一下2022-05-05

