在阅读了Guido的Sorting a million 32-bit integers in 2MB of RAM using Python之后,我发现了heapq
模块,但这个概念对我来说非常抽象。
一个原因是我完全不了解堆的概念,但我确实理解Guido如何使用它。
现在,除了他那种疯狂的例子之外,你会用heapq
模块做什么?
它必须始终与排序或最小值相关吗?它只是你使用的东西,因为它比其他方法更快?或者你可以做一些你不能没有的优雅事物吗?
答案 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)
将它与自平衡二叉树进行比较,如果只看复杂性,堆似乎不会带来太多收益:
但是,虽然二叉树往往需要每个节点指向其子节点以提高效率,但是堆将其数据紧密地存储到数组中。这允许您在固定数量的内存中存储更多数据。
因此,对于只需要插入和最大删除的情况,堆是完美的,并且通常可以使用一半的内存作为自平衡二叉树(如果必须,更容易实现)。标准用例是优先级队列。
答案 2 :(得分:3)
通过试图了解如何在Python 2.6中实现计数器模块,这是对我的偶然发现。只需了解collections.Counter的实施和使用情况。这实际上是通过heapq实现的。