class queue.PriorityQueue(maxsize=0)
優先級隊列構造函數。 maxsize 是個整數,用於設置可以放入隊列中的項目數的上限。當達到這個大小的時候,插入操作將阻塞至隊列中的項目被消費掉。如果 maxsize 小於等於零,隊列尺寸為無限大。
最小值先被取出( 最小值條目是由 sorted(list(entries))[0] 返回的條目)。條目的典型模式是一個以下形式的元組: (priority_number, data) 。
如果 data 元素沒有可比性,數據將被包裝在一個類中,忽略數據值,僅僅比較優先級數字 :
1 from dataclasses import dataclass, field 2 from typing import Any 3
4 @dataclass(order=True) 5 class PrioritizedItem: 6 priority: int 7 item: Any=field(compare=False)
Queue對象
隊列對象 (Queue, LifoQueue, 或者 PriorityQueue) 提供下列描述的公共方法。
-
Queue.qsize() -
返回隊列的大致大小。注意,qsize() > 0 不保證后續的 get() 不被阻塞,qsize() < maxsize 也不保證 put() 不被阻塞。
-
Queue.empty() -
如果隊列為空,返回
True,否則返回False。如果 empty() 返回True,不保證后續調用的 put() 不被阻塞。類似的,如果 empty() 返回False,也不保證后續調用的 get() 不被阻塞。
-
Queue.full() -
如果隊列是滿的返回
True,否則返回False。如果 full() 返回True不保證后續調用的 get() 不被阻塞。類似的,如果 full() 返回False也不保證后續調用的 put() 不被阻塞。
-
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 將被忽略)。POSIX系統3.0之前,以及所有版本的Windows系統中,如果 block 是 true 並且 timeout 是
None, 這個操作將進入基礎鎖的不間斷等待。這意味着,沒有異常能發生,尤其是 SIGINT 將不會觸發KeyboardInterrupt異常。
-
Queue.get_nowait() -
相當於
get(False)。
提供了兩個方法,用於支持跟蹤 排隊的任務 是否 被守護的消費者線程 完整的處理。
-
Queue.task_done() -
表示前面排隊的任務已經被完成。被隊列的消費者線程使用。每個
get()被用於獲取一個任務, 后續調用task_done()告訴隊列,該任務的處理已經完成。如果
join()當前正在阻塞,在所有條目都被處理后,將解除阻塞(意味着每個put()進隊列的條目的task_done()都被收到)。如果被調用的次數多於放入隊列中的項目數量,將引發
ValueError異常 。
-
Queue.join() -
阻塞至隊列中所有的元素都被接收和處理完畢。
當條目添加到隊列的時候,未完成任務的計數就會增加。每當消費者線程調用
task_done()表示這個條目已經被回收,該條目所有工作已經完成,未完成計數就會減少。當未完成計數降到零的時候,join()阻塞被解除。
如何等待排隊的任務被完成的示例:
1 def worker(): 2 while True: 3 item = q.get() 4 if item is None: 5 break
6 do_work(item) 7 q.task_done() 8
9 q = queue.Queue() 10 threads = [] 11 for i in range(num_worker_threads): 12 t = threading.Thread(target=worker) 13 t.start() 14 threads.append(t) 15
16 for item in source(): 17 q.put(item) 18
19 # block until all tasks are done
20 q.join() 21
22 # stop workers
23 for i in range(num_worker_threads): 24 q.put(None) 25 for t in threads: 26 t.join()
一道leetcode題目:
347. Top K Frequent Elements 前K個高頻元素
給定一個非空的整數數組,返回其中出現頻率前 k 高的元素。
示例 1:
輸入: nums = [1,1,1,2,2,3], k = 2 輸出: [1,2]
示例 2:
輸入: nums = [1], k = 1 輸出: [1]
說明:
- 你可以假設給定的 k 總是合理的,且 1 ≤ k ≤ 數組中不相同的元素的個數。
- 你的算法的時間復雜度必須優於 O(n log n) , n 是數組的大小。
1 class Solution: 2 def topKFrequent(self, nums, k: int): 3 if k<0 or k>len(nums): return [] 4 from queue import PriorityQueue 5 from collections import defaultdict 6 queue = PriorityQueue() 7 d = defaultdict(int) 8 res = [] 9 for i in nums: 10 d[i]+=1
11 d = list(d.items()) 12 print(d) 13 for i in range(len(d)): 14 queue.put([-d[i][1],d[i][0]]) 15 for i in range(k): 16 res.append(queue.get()[1]) 17 return res
參考自 Python 標准庫
