Python數(shù)據(jù)結(jié)構(gòu)之隊(duì)列
python內(nèi)置的queue模塊實(shí)現(xiàn)了三種類型的隊(duì)列,因此沒有必要重復(fù)造輪子,它們的區(qū)別僅僅是條目取回的順序。在 FIFO 隊(duì)列中,先添加的任務(wù)先取回。在 LIFO 隊(duì)列中,最近被添加的條目先取回(操作類似一個(gè)堆棧)。優(yōu)先級隊(duì)列中,條目將保持排序( 使用 heapq 模塊 ) 并且最小值的條目第一個(gè)返回。
- class queue.Queue(maxsize=0)
FIFO 先入先出隊(duì)列構(gòu)造函數(shù)。maxsize 是個(gè)整數(shù),用于設(shè)置可以放入隊(duì)列中的項(xiàng)目數(shù)的上限。當(dāng)達(dá)到這個(gè)大小的時(shí)候,插入操作將阻塞至隊(duì)列中的項(xiàng)目被消費(fèi)掉。如果 maxsize 小于等于零,隊(duì)列尺寸為無限大。
- maxsize is an integer that sets the upperbound limit on the number of items that can be placed in the queue.
- class queue.LifoQueue(maxsize=0)
LIFO 后入先出隊(duì)列構(gòu)造函數(shù)。maxsize 是個(gè)整數(shù),用于設(shè)置可以放入隊(duì)列中的項(xiàng)目數(shù)的上限。當(dāng)達(dá)到這個(gè)大小的時(shí)候,插入操作將阻塞至隊(duì)列中的項(xiàng)目被消費(fèi)掉。如果 maxsize 小于等于零,隊(duì)列尺寸為無限大。
- class queue.PriorityQueue(maxsize=0)
PriorityQueue優(yōu)先級隊(duì)列構(gòu)造函數(shù)。maxsize 是個(gè)整數(shù),用于設(shè)置可以放入隊(duì)列中的項(xiàng)目數(shù)的上限。當(dāng)達(dá)到這個(gè)大小的時(shí)候,插入操作將阻塞至隊(duì)列中的項(xiàng)目被消費(fèi)掉。如果 maxsize 小于等于零,隊(duì)列尺寸為無限大。
通用方法:
Queue.qsize() 返回隊(duì)列的大致大小
Queue.empty() 如果隊(duì)列為空,返回 True ,否則返回 False 。
Queue.full() 如果隊(duì)列是滿的返回 True ,否則返回 False 。
Queue.put(item, block=True, timeout=None) 將 item 放入隊(duì)列。
如果可選參數(shù) block 是 true 并且 timeout 是 None (默認(rèn)),則在必要時(shí)阻塞至有空閑插槽可用。
如果 timeout 是個(gè)正數(shù),將最多阻塞 timeout 秒,如果在這段時(shí)間沒有可用的空閑插槽,將引發(fā) Full 異常。
反之 (block 是 false),如果空閑插槽立即可用,則把 item 放入隊(duì)列,否則引發(fā) Full 異常 ( 在這種情況下,timeout 將被忽略)。
Queue.put_nowait(item) 相當(dāng)于 put(item, False) 。
Queue.get(block=True, timeout=None) 從隊(duì)列中移除并返回一個(gè)項(xiàng)目。
如果可選參數(shù) block 是 true 并且 timeout 是 None (默認(rèn)值),則在必要時(shí)阻塞至項(xiàng)目可得到。
如果 timeout 是個(gè)正數(shù),將最多阻塞 timeout 秒,如果在這段時(shí)間內(nèi)項(xiàng)目不能得到,將引發(fā) Empty 異常。
反之 (block 是 false) , 如果一個(gè)項(xiàng)目立即可得到,則返回一個(gè)項(xiàng)目,否則引發(fā) Empty 異常 (這種情況下,timeout 將被忽略)。
Queue.get_nowait() 相當(dāng)于 get(False) 。
提供了兩個(gè)方法,用于支持跟蹤 排隊(duì)的任務(wù) 是否 被守護(hù)的消費(fèi)者線程 完整的處理。
- Queue.task_done()
表示前面排隊(duì)的任務(wù)已經(jīng)被完成。被隊(duì)列的消費(fèi)者線程使用。每個(gè) get() 被用于獲取一個(gè)任務(wù), 后續(xù)調(diào)用 task_done() 告訴隊(duì)列,該任務(wù)的處理已經(jīng)完成。
如果 join() 當(dāng)前正在阻塞,在所有條目都被處理后,將解除阻塞(意味著每個(gè) put() 進(jìn)隊(duì)列的條目的 task_done() 都被收到)。
如果被調(diào)用的次數(shù)多于放入隊(duì)列中的項(xiàng)目數(shù)量,將引發(fā) ValueError 異常 。
- Queue.join()
阻塞至隊(duì)列中所有的元素都被接收和處理完畢。
當(dāng)條目添加到隊(duì)列的時(shí)候,未完成任務(wù)的計(jì)數(shù)就會增加。
每當(dāng)消費(fèi)者線程調(diào)用 task_done() 表示這個(gè)條目已經(jīng)被回收,該條目所有工作已經(jīng)完成,未完成計(jì)數(shù)就會減少。
當(dāng)未完成計(jì)數(shù)降到零的時(shí)候, join() 阻塞被解除。
代碼如下:
- #!/usr/bin/env python
- # -*- coding: UTF-8 -*-
- # _ooOoo_
- # o8888888o
- # 88" . "88
- # ( | - _ - | )
- # O\ = /O
- # ____/`---'\____
- # .' \\| |// `.
- # / \\|||:|||// \
- # / _|||||-:- |||||- \
- # | | \\\ - /// | |
- # | \_| ''\---/'' | _/ |
- # \ .-\__ `-` ___/-. /
- # ___`. .' /--.--\ `. . __
- # ."" '< `.___\_<|>_/___.' >'"".
- # | | : `- \`.;`\ _ /`;.`/ - ` : | |
- # \ \ `-. \_ __\ /__ _/ .-` / /
- # ==`-.____`-.___\_____/___.-`____.-'==
- # `=---='
- '''
- @Project :pythonalgorithms
- @File :queuedatastructure.py
- @Author :不勝人生一場醉
- @Date :2021/7/15 1:53
- '''
- from queue import Queue, LifoQueue, PriorityQueue, SimpleQueue
- import random
- if __name__ == '__main__':
- q = Queue() # 先進(jìn)先出隊(duì)列
- lq = LifoQueue() # 先進(jìn)后廚隊(duì)列
- pq = PriorityQueue() # 優(yōu)先級隊(duì)列
- sq = SimpleQueue() # 簡單隊(duì)列
- # 插入隊(duì)列數(shù)據(jù)
- for i in range(10):
- q.put(i)
- lq.put(i)
- pq.put(random.randint(1, 20), i)
- sq.put(i)
- for i in range(10):
- print(q.get(), end=' ')
- # 0 1 2 3 4 5 6 7 8 9
- print('\r')
- for i in range(10):
- print(lq.get(), end=' ')
- # 9 8 7 6 5 4 3 2 1 0
- print('\r')
- for i in range(10):
- print(pq.get(), end=' ')
- # 6 7 13 16 17 18 18 19 20 20
- print('\r')
- for i in range(10):
- print(sq.get(), end=' ')
- # 0 1 2 3 4 5 6 7 8 9
- q = Queue(3)
- print('\r')
- print('queue.qsize=', q.qsize())
- # queue.qsize= 0
- print('queue.empty=', q.empty())
- # queue.empty= True
- q.put(5)
- q.put(9)
- q.put(1)
- print('queue.full=', q.full())
- # queue.full= True
- # q.put(10)
- # print(q)
- # q.put(11,block=True,timeout=1) #在timeout=1秒左右,返回 raise Full
- # print(q)
- # q.put(11, block=False, timeout=1) # 立刻 返回 raise Full,忽略時(shí)間
- # print(q)
輸出結(jié)果為: