python 中的 heapq 和 PriorityQueue 有什么区别?

What's the difference between heapq and PriorityQueue in python?

在 python 中有一个内置的 heapq algorithm that gives you push, pop, nlargest, nsmallest... etc that you can apply to lists. However, there's also the queue.PriorityQueue class 似乎支持或多或少相同的功能。有什么区别,你什么时候会用一个而不是另一个?

Queue.PriorityQueue 是线程安全的 class,而 heapq 模块不提供线程安全保证。来自 Queue module documentation:

The Queue module implements multi-producer, multi-consumer queues. It is especially useful in threaded programming when information must be exchanged safely between multiple threads. The Queue class in this module implements all the required locking semantics. It depends on the availability of thread support in Python; see the threading module.

heapq 模块不提供锁定,并在标准 list 对象上运行,这些对象不是线程安全的。

事实上,PriorityQueue 实现 在后台使用 heapq 来完成所有优先级排序工作,基础 Queue class 提供锁定以使其成为线程安全的。有关详细信息,请参阅 source code

这使得 heapq 模块更快;没有锁定开销。此外,您可以以不同的新颖方式自由使用各种 heapq 功能,PriorityQueue 仅提供直接排队功能。

queue.PriorityQueueheapq class.

的部分包装

换句话说,一个queue.PriorityQueue实际上是一个heapq,放在队列模块中,有几个重命名的方法使heapq更容易使用,很像常规队列。

heapq 中,您使用方法 heappush() 添加新项目,使用方法 heappop() 删除项目。这不是很像队列,所以 queue.PriorityQueue 允许您使用常用的队列方法,例如 putget 来做同样的事情。

heapq 的某些功能没有带入 queue.PriorityQueue,例如 heappushpop()heapreplace(),但您不太可能使用这些功能。如果您需要它们(我在当前项目中需要),也许您应该使用 heapq 而不是 queue.PriorityQueue.

此外,由于 heapq 专门用于其用途,因此它不是线程安全的(如此处的另一个答案所述。)