当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


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。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。