【问题标题】:What would you use the heapq Python module for in real life?你会在现实生活中使用 heapq Python 模块做什么?
【发布时间】:2012-01-27 11:11:04
【问题描述】:

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

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

现在,除了他有点疯狂的例子,你会将heapq 模块用于什么?

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

【问题讨论】:

  • 您是否尝试阅读 heapq 模块的文档以了解它的作用?
  • 当你有 40K+ 代表时很难被问到这个问题,但奇怪的是它仍然会发生。

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


【解决方案1】:

heapq module 通常用于实现priority queues

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

heapq 文档包括解决常见用例的priority queue implementation notes

此外,堆非常适合实现部分排序。例如,heapq.nsmallestheapq.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]

【讨论】:

  • 3 个现实生活中的例子。正是我需要的。
【解决方案2】:

将它与自平衡二叉树相比,如果只看复杂性,堆似乎并没有给你带来太多好处:

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

但是,为了提高效率,二叉树往往需要每个节点都指向其子节点,而堆则将其数据紧密地存储在一个数组中。这使您可以在固定数量的内存中存储更多数据。

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

【讨论】:

  • 更紧凑的数据表示也可能会提高缓存性能。
【解决方案3】:

这是我在尝试了解如何在 Python 2.6 中实现计数器模块时偶然发现的。只需看看collections.Counter 的实现和使用。这其实是通过heapq实现的。

【讨论】:

  • Counter 类是 dict 的子类。 heapq.nlargest 方法用于有效地找到 n 个最常见的元素。
  • @Raymond ...按降序排列(否则堆不是最有效的方法)。
  • @PaulHankin 你确定吗?见code.activestate.com/recipes/…
  • @Raymond 有趣的链接!但我的意思是,如果您不想对它们进行排序,那么仅进行快速选择具有更好的复杂性。但实际上,log k 项可能并不相关。
猜你喜欢
  • 2019-05-01
  • 2013-11-27
  • 1970-01-01
  • 2018-03-02
  • 2018-01-12
  • 1970-01-01
  • 1970-01-01
  • 2011-12-02
  • 2021-01-16
相关资源
最近更新 更多