Python數據結構之隊列
python內置的queue模塊實現了三種類型的隊列,因此沒有必要重復造輪子,它們的區別僅僅是條目取回的順序。在 FIFO 隊列中,先添加的任務先取回。在 LIFO 隊列中,最近被添加的條目先取回(操作類似一個堆棧)。優先級隊列中,條目將保持排序( 使用 heapq 模塊 ) 并且最小值的條目第一個返回。
- class queue.Queue(maxsize=0)
FIFO 先入先出隊列構造函數。maxsize 是個整數,用于設置可以放入隊列中的項目數的上限。當達到這個大小的時候,插入操作將阻塞至隊列中的項目被消費掉。如果 maxsize 小于等于零,隊列尺寸為無限大。
- 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 后入先出隊列構造函數。maxsize 是個整數,用于設置可以放入隊列中的項目數的上限。當達到這個大小的時候,插入操作將阻塞至隊列中的項目被消費掉。如果 maxsize 小于等于零,隊列尺寸為無限大。
- class queue.PriorityQueue(maxsize=0)
PriorityQueue優先級隊列構造函數。maxsize 是個整數,用于設置可以放入隊列中的項目數的上限。當達到這個大小的時候,插入操作將阻塞至隊列中的項目被消費掉。如果 maxsize 小于等于零,隊列尺寸為無限大。
通用方法:
Queue.qsize() 返回隊列的大致大小
Queue.empty() 如果隊列為空,返回 True ,否則返回 False 。
Queue.full() 如果隊列是滿的返回 True ,否則返回 False 。
Queue.put(item, block=True, timeout=None) 將 item 放入隊列。
如果可選參數 block 是 true 并且 timeout 是 None (默認),則在必要時阻塞至有空閑插槽可用。
如果 timeout 是個正數,將最多阻塞 timeout 秒,如果在這段時間沒有可用的空閑插槽,將引發 Full 異常。
反之 (block 是 false),如果空閑插槽立即可用,則把 item 放入隊列,否則引發 Full 異常 ( 在這種情況下,timeout 將被忽略)。
Queue.put_nowait(item) 相當于 put(item, False) 。
Queue.get(block=True, timeout=None) 從隊列中移除并返回一個項目。
如果可選參數 block 是 true 并且 timeout 是 None (默認值),則在必要時阻塞至項目可得到。
如果 timeout 是個正數,將最多阻塞 timeout 秒,如果在這段時間內項目不能得到,將引發 Empty 異常。
反之 (block 是 false) , 如果一個項目立即可得到,則返回一個項目,否則引發 Empty 異常 (這種情況下,timeout 將被忽略)。
Queue.get_nowait() 相當于 get(False) 。
提供了兩個方法,用于支持跟蹤 排隊的任務 是否 被守護的消費者線程 完整的處理。
- Queue.task_done()
表示前面排隊的任務已經被完成。被隊列的消費者線程使用。每個 get() 被用于獲取一個任務, 后續調用 task_done() 告訴隊列,該任務的處理已經完成。
如果 join() 當前正在阻塞,在所有條目都被處理后,將解除阻塞(意味著每個 put() 進隊列的條目的 task_done() 都被收到)。
如果被調用的次數多于放入隊列中的項目數量,將引發 ValueError 異常 。
- Queue.join()
阻塞至隊列中所有的元素都被接收和處理完畢。
當條目添加到隊列的時候,未完成任務的計數就會增加。
每當消費者線程調用 task_done() 表示這個條目已經被回收,該條目所有工作已經完成,未完成計數就會減少。
當未完成計數降到零的時候, 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() # 先進先出隊列
- lq = LifoQueue() # 先進后廚隊列
- pq = PriorityQueue() # 優先級隊列
- sq = SimpleQueue() # 簡單隊列
- # 插入隊列數據
- 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,忽略時間
- # print(q)
輸出結果為: