當前位置: 首頁>>編程示例 >>用法及示例精選 >>正文


Python heapq和PriorityQueue的區別用法及代碼示例

在本文中,我們將在 Python 中看到 heapq 和 PriorityQueue 之間的區別。

PriorityQueue 和 heapq 之間的區別

  • Python隊列PriorityQueue是線程安全的,但heapq不保證線程安全。
  • PriorityQueue實現了鎖定來保證線程安全,因此比heapq慢。
  • heapq 就地堆放原始列表,而使用 PriorityQueue 時它不會修改原始數據。
  • heapq 的工作原理是二叉堆,而PriorityQueue 的工作原理是queue 數據結構,並且可以分配優先級。
  • 在多個線程中使用相同的 PriorityQueue 並進行修改是安全的,但在 heapq 的情況下,它可能會導致數據競爭條件,因為操作隊列時沒有鎖。

使用 heapq 和 PriorityQueue 的語法

示例 1:使用 heapq

在這裏,我們使用heapify()方法將項目列表轉換為堆。然後我們使用heapop()方法從堆列表中一項一項地彈出項目。

Python3


import heapq
jobs = [(1, 'eat'), (3, 'code'), (2, 'sleep')]
heapq.heapify(jobs)
for _ in range(len(jobs)):
  popped_item = heapq.heappop(jobs)
  print(popped_item)

輸出:

(1, 'eat')
(2, 'sleep')
(3, 'code')

示例 2:使用PriorityQueue

在這裏,我們使用.put()方法將一個元素推送到PriorityQueue,並使用get_nowait()從PriorityQueue中彈出一個元素。當 PriorityQueue 引發 Empty 異常時,從 PriorityQueue 彈出項目的循環將中斷,這表示沒有更多元素要彈出。

Python3


from queue import PriorityQueue, Empty
prior_queue = PriorityQueue()
jobs = [(1, 'eat'), (3, 'code'), (2, 'sleep')]
for job in jobs:
  prior_queue.put(job)
  while 1:
    try:
      popped_item = prior_queue.get_nowait()
      print(popped_item)
    except Empty:
      break

輸出:

(1, 'eat')
(3, 'code')
(2, 'sleep')

heapq 與 PriorityQueue 的時間比較

在這裏,我們為兩個不同的目的定義了 2 個函數。p_queue()在 10^5 數據項上使用 PriorityQueue 的函數。和heap_queue()在相同大小的數據輸入列表上使用 heapq 執行操作Python模塊。還有main()用於對上述兩個函數進行時間分析的函數。

Python3


import time
from queue import PriorityQueue, Empty
import heapq
def p_queue():
    prior_queue = PriorityQueue()
    jobs = [(x, f"This is item: {x}") for x in range(1, 10 ** 5 + 1)]
    for job in jobs:
        prior_queue.put(job)
    while 1:
        try:
            popped_item = prior_queue.get_nowait()
        except Empty:
            break
def heap_queue():
    jobs = [(x, f"This is item: {x}") \
            for x in range(1, 10 ** 5 + 1)]
    heapq.heapify(jobs)
    for _ in range(len(jobs)):
        popped_item = heapq.heappop(jobs)
def main():
    start_time = time.perf_counter_ns()
    heap_queue()
    end_time = time.perf_counter_ns()
    print(f"Adding and popping item using heapq \
    took: {(end_time - start_time) // 10 ** 6:.02f}ms")
    start_time = time.perf_counter_ns()
    p_queue()
    end_time = time.perf_counter_ns()
    print(f"Adding and popping item using PriorityQueue\
    took: {(end_time - start_time) // 10 ** 6:.02f}ms")
if __name__ == '__main__':
    main()

輸出:

Adding and popping item using heapq took: 154.00ms

Adding and popping item using PriorityQueue took: 375.00ms

結論:從時間分析中可以清楚地看出,heapq 的運行速度比 PriorityQueue 函數更快。這是顯而易見的,因為 PriorityQueue 使用線程模塊來實現互斥結構,以在操作隊列中的項目時實現線程安全。



相關用法


注:本文由純淨天空篩選整理自tuhinmi74jn大神的英文原創作品 Difference Between heapq and PriorityQueue in Python。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。