你会在现实生活中使用heapq Python模块吗?

时间:2011-12-24 22:02:43

标签: python algorithm data-structures heap priority-queue

在阅读了Guido的Sorting a million 32-bit integers in 2MB of RAM using Python之后,我发现了heapq模块,但这个概念对我来说非常抽象。

一个原因是我完全不了解堆的概念,但我确实理解Guido如何使用它。

现在,除了他那种疯狂的例子之外,你会用heapq模块做什么?

它必须始终与排序或最小值相关吗?它只是你使用的东西,因为它比其他方法更快?或者你可以做一些你不能没有的优雅事物吗?

3 个答案:

答案 0 :(得分:19)

heapq module通常用于实施priority queues

您会在事件调度程序中看到不断添加新事件的优先级队列,并且需要使用堆来有效地定位下一个调度事件。一些例子包括:

heapq文档包含priority queue implementation notes,它解决了常见的用例。

此外,堆很适合实现部分排序。例如, heapq.nsmallest heapq.nlargest 可以提高内存效率,并且比完整排序后跟切片执行的比较要少得多:

>>> from heapq import nlargest
>>> from random import random
>>> nlargest(5, (random() for i in xrange(1000000)))
[0.9999995650034837, 0.9999985756262746, 0.9999971934450994, 0.9999960394998497, 0.9999949126363714]

答案 1 :(得分:6)

将它与自平衡二叉树进行比较,如果只看复杂性,堆似乎不会带来太多收益:

  • 插入:两者都是O(logN)
  • 删除两个
  • 的最大元素:O(logN)
  • 从堆的元素数组O(N)构建结构,为二叉树构建O(N log N)。

但是,虽然二叉树往往需要每个节点指向其子节点以提高效率,但是堆将其数据紧密地存储到数组中。这允许您在固定数量的内存中存储更多数据。

因此,对于只需要插入和最大删除的情况,堆是完美的,并且通常可以使用一半的内存作为自平衡二叉树(如果必须,更容易实现)。标准用例是优先级队列。

答案 2 :(得分:3)

通过试图了解如何在Python 2.6中实现计数器模块,这是对我的偶然发现。只需了解collections.Counter的实施和使用情况。这实际上是通过heapq实现的。

相关问题