Python 如何在不丢失数据的情况下迭代heapq?

Python 如何在不丢失数据的情况下迭代heapq?,python,python-3.x,heapq,Python,Python 3.x,Heapq,在Python 3中,我使用heapq,如下所示: import heapq heap = [3] heapq.heapify(heap) heapq.heappush(heap, 5) # Push more values... # I can iterate heap like so, but by the end it will be empty: while (heap): curr = heapq.heappop(heap) # Do whatever with c

在Python 3中,我使用heapq,如下所示:

import heapq

heap = [3]
heapq.heapify(heap)
heapq.heappush(heap, 5)
# Push more values...

# I can iterate heap like so, but by the end it will be empty:
while (heap):
    curr = heapq.heappop(heap)
    # Do whatever with curr
有没有一种方法可以迭代heapq,这样我就可以在不改变heapq/丢失数据的情况下按排序顺序获取值?

如果没有,我如何有效地模仿所需的行为?

我提出的解决方案是创建一个临时堆,当我从原始堆弹出时将其推入,一旦完成迭代,将原始堆设置为临时堆

当然,这不是很有效,并且会更改原始堆引用的对象

temp = []
heapq.heapify(temp)

while(heap):
    curr = heapq.heappop(heap)
    heapq.heappush(temp, curr)
    # Do whatever with curr
heap = temp

如果您想要的只是堆上的所有值,按照排序顺序,那么只需对堆进行排序。使用将按排序顺序提供序列,而不改变堆列表本身:

sorted(heap)
或者,由于按排序顺序排列的列表也是一个有效堆,请对堆进行适当排序:

heap.sort()
使用的排序算法得益于堆结构中固有的偏序,并且肯定比逐个从堆中弹出值然后构建新堆更有效


heap
值本身并没有什么特别之处,顺便说一下,它只是一个列表。还要注意,堆是一种数据结构,旨在让您有效地访问最低(或最高)值,而不是完全迭代。它本质上是一棵二叉树,树的每一层都按深度顺序排列成一个列表。

如果您只想按排序顺序排列堆上的所有值,那么只需对堆进行排序即可。使用将按排序顺序提供序列,而不改变堆列表本身:

sorted(heap)
或者,由于按排序顺序排列的列表也是一个有效堆,请对堆进行适当排序:

heap.sort()
使用的排序算法得益于堆结构中固有的偏序,并且肯定比逐个从堆中弹出值然后构建新堆更有效


heap
值本身并没有什么特别之处,顺便说一下,它只是一个列表。还要注意,堆是一种数据结构,旨在让您有效地访问最低(或最高)值,而不是完全迭代。它本质上是一棵二叉树,树的每一层都按深度顺序排列成一个列表。

堆不是要迭代的。你能解释一下你想做什么吗?堆不是要迭代的。你能解释一下你想做什么吗?偏序似乎帮不了什么忙。我试着对一百万个随机数进行排序,并在重排序后对相同的数进行排序,后者只比前者快5%左右。@HeapOverflow:5%仍然是一个胜利!当然,这就是为什么我说它“帮助不大”:-。我甚至不知道提姆索特的哪一部分是加速的原因。这并不是说已经有很长时间的跑步了。最长出现的运行长度为10个元素,远低于最小运行(=32),仅略长于随机顺序中出现的最长运行长度,即9个元素。平均游程长度只有2.55个元素(随机顺序为2.50)。@HeapOverflow:我没有详细检查这一点,但我怀疑合并时的疾驰模式得益于树深度之间两个距离的力量。偏序似乎对Timsort没有多大帮助。我试着对一百万个随机数进行排序,并在重排序后对相同的数进行排序,后者只比前者快5%左右。@HeapOverflow:5%仍然是一个胜利!当然,这就是为什么我说它“帮助不大”:-。我甚至不知道提姆索特的哪一部分是加速的原因。这并不是说已经有很长时间的跑步了。最长出现的运行长度为10个元素,远低于最小运行(=32),仅略长于随机顺序中出现的最长运行长度,即9个元素。平均运行长度只有2.55个元素(随机顺序为2.50)。@HeapOverflow:我没有详细检查这个,但我怀疑合并时的疾驰模式得益于树深之间两个距离的力量。