如何有效地弹出堆q中最小键的所有元素?

时间:2019-01-17 03:23:58

标签: python priority-queue pop heapq

我正在做一个模拟实验,并试图使我的代码尽可能高效。在一部分中,我有一个最小堆优先级队列,该队列已使用heapq模块实现。

在整个模拟过程中,我必须使用最小的键弹出所有元素。这样做的简单方法是:

    elements = []
    k1, v1 = heapq.heappop(heap)
    elements.append((k1,v1))
    k2, v2 = heap[0] #looks at the smallest item without popping
    while(k1 == k2):
         k1, v1 = heapq.heappop(heap)
         elements.append((k1,v1))
         k2, v2 = heap[0]
    return elements

2 个答案:

答案 0 :(得分:1)

您展示的一般技术是最有效且最简单的。但是您正在做不必要的额外任务。下面是一个小的优化。

elements = []
k1, v1 = heapq.heappop(heap)
elements.append((k1,v1))
while(k1 == heap[0]):
     k2, v2 = heapq.heappop(heap)
     elements.append((k2,v2))
return elements

为了安全起见,您可能应该添加检查以确保堆不为空。在堆中没有任何项目时检查heap[0]是一件坏事,如果堆为空,则调用heapq.heappop也是一件坏事。

答案 1 :(得分:0)

我打算建议将结构从堆(k, v)更改为k和字典{k:[v]}。这会将您的代码转换为:

k = heap[0]
return [(k,v) for v in hash[k]]

使用:

hash = defaultdict(list)
heap = []

heappush(heap, (k, v))将变为:

heappush(heap, k)
hash[k].append(v)

heappop(heap)将变为:

k = heappop(heap)
v = hash[k].pop()