Python heapq与排序的复杂性和性能

时间:2014-07-10 02:33:16

标签: python performance sorting heap complexity-theory

我对python相对较新(使用v3.x语法),并且会喜欢关于heapq与已排序的复杂性和性能的注释。

我已经实施了基于heapq的解决方案,以便贪婪地找到最佳的工作时间表'算法。但后来我了解到使用“排序”的可能性。与operator.itemgetter()和reverse = True一起使用。

可悲的是,我找不到关于“排序”的预期复杂性和/或性能的任何解释。与heapq。

3 个答案:

答案 0 :(得分:9)

如果您使用二进制堆按顺序弹出所有元素,那么您所做的事情基本上是heapsort。它比sorted function中的algorightm更慢,除了它的实现是纯python。

如果您需要动态添加元素,heapqsorted更快,即添加和插入可能会以未指定的顺序排列。在任何堆中添加保留内部顺序的新元素比在每次插入后使用数组更快。

如果您需要稍后检索所有元素,sorted会更快。

他们可以竞争的唯一问题 - 如果你需要收集的一些最小(或最大)元素。虽然there are special algorigthms for that case heapqsorted在这里会更快,但取决于初始数组的大小和您需要提取的部分。

答案 1 :(得分:1)

heapq实现为二进制堆, 关于二进制堆以及扩展名heapq的关键注意事项:

  1. 不支持搜索
  2. 插入是平均的固定时间
  3. 删除 O(log n)平均时间
  4. 此处描述的其他二进制堆信息:http://en.wikipedia.org/wiki/Binary_heap

    虽然heapq数据结构,其具有二进制堆的属性,但使用sorted是一个不同的概念。 sorted会返回排序列表,因此这实际上是一个结果,而heapq是您不断使用的数据结构,可以,可选地,可以通过sorted进行排序。

    此处添加个人sorted信息:https://docs.python.org/3.4/library/functions.html#sorted

    你想要完成什么?

    对OP评论的回应:

    为什么您认为自己需要heapq二进制堆是一个专门的数据结构,根据您的要求,很可能没有必要。

    你似乎非常关心表现,但目前尚不清楚原因。如果有什么东西是“表现不好”,但它的总时间并不重要,那么从大局来看,这无关紧要。在总体情况下,dictlist通常会执行罚款。为什么你特别认为需要heapq

    我想知道这是否是一个不让这个完美的敌人 - 好的类型的情况。

    使用 C扩展编写 Python 是一个利基用例,保留用于性能确实是一个重要问题的情况。 (也就是说,使用 XML 解析器可能更好,这是 C扩展,而不是纯粹的 Python ,如果你是处理大型文件,如果性能是您主要关心的问题。)

    关于在复杂中继续玩结构案例:通过.append()对排序和添加元素进行排序可能更快:

    我还不清楚这里的用例是什么。如上所述,sortedheapq实际上是两个不同的概念。

    您对性能如此关注的用例是什么? (如果没有其他尚未指定的因素,我认为您可能过分强调了代码中最佳案例性能的重要性。)

答案 2 :(得分:0)

nlargest()的{​​{1}}和nsmallest()函数最适合用于查找数量相对较少的项目。如果只想查找一个最小或最大的数字,则min()和max()最合适,因为它速度更快,并且使用heapq然后进行切片。如果您正在寻找N个最小或最大的项目,并且N与集合的整体大小相比较小,则这些功能可提供卓越的性能。尽管不必在代码中使用heapq,但这只是一个有趣的话题,也是一个值得研究的主题。