保持固定大小的堆-python

时间:2015-05-25 17:18:55

标签: python

h = []
heapq.heappush(h,(10, 1200))
heapq.heappush(h,(20, 31))
heapq.heappush(h,(5, 1))

我想保持固定堆大小为3,所以当我接下来有heapq.heappush(h,(3,15))时,值为20的键被删除,我留下值3,5和10.任何想法如何?

5 个答案:

答案 0 :(得分:7)

heapq中没有内置来检查大小,所以你必须自己做:

if len(h) < capacity:
    heapq.heappush(h, thing)
else:
    # Equivalent to a push, then a pop, but faster
    spilled_value = heapq.heappushpop(h, thing)
    do_whatever_with(spilled_value)

另请注意,heapq实现了最小堆,而不是最大堆。你需要颠倒你的优先顺序,可能是否定它们。

答案 1 :(得分:0)

我发现我试图实现固定大小的top-n堆,这是我可以提供的解决方案:

from heapq import heapify, heappush, heappushpop

class MaxHeap():
    def __init__(self, top_n):
        self.h = []
        self.length = top_n
        heapify( self.h)

    def add(self, element):
        if len(self.h) < self.length:
            heappush(self.h, element)
        else:
            heappushpop(self.h, element)

    def getTop(self):
        return sorted(self.h, reverse=True)

答案 2 :(得分:0)

如果您想要 k 个最小的元素,这等效于在每次推送时都丢弃固定大小的最小堆的最大元素,则应使用heapq.nsmallest(或{{ 1}}(相反)在您要从中构建堆的可迭代对象上。

答案 3 :(得分:0)

Python(截至今天的3.8x版本)没有内置的固定堆大小功能。您有2个选择:

  1. 维护一个堆,并在每次推送时检查size > fixedSize是否弹出。这意味着在任何给定时间,您的堆的最大大小可能是fixedSize+1,这是您弹出一个堆的时间。

  2. 另一种选择是使用docs中的heapq.heapreplace(heap, item)

弹出并从堆中返回最小的项,然后还推送新项。堆大小不变。如果堆为空,则会引发IndexError。 一步操作比heapush()和heappush()高效,并且在使用固定大小的堆时更合适。

答案 4 :(得分:0)

我自己需要这样的东西,一个具有最大长度的排序列表。

我使用了双端队列,因为它有 'maxlen' 属性。

import collections
import bisect

h = collections.deque(maxlen=3)

def insert(h, item):
    if len(h) < h.maxlen or item < h[-1]:
        if len(h) == h.maxlen:
            h.pop()
        bisect.insort_left(h, item)

>>> insert(h, 200); print(h)
deque([200], maxlen=3)

>>> insert(h, 100); print(h)
deque([100, 200], maxlen=3)

>>> insert(h, 200); print(h)
deque([100, 200, 200], maxlen=3)

>>> insert(h, 150); print(h)
deque([100, 150, 200], maxlen=3)

>>> insert(h, 200); print(h)
deque([100, 150, 200], maxlen=3)

>>> insert(h, 1); print(h)
deque([1, 100, 150], maxlen=3)

>>> insert(h, 100); print(h)
deque([1, 100, 100], maxlen=3)

>>> insert(h, 20); print(h)
deque([1, 20, 100], maxlen=3)