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.任何想法如何?
答案 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个选择:
维护一个堆,并在每次推送时检查size > fixedSize
是否弹出。这意味着在任何给定时间,您的堆的最大大小可能是fixedSize+1
,这是您弹出一个堆的时间。
另一种选择是使用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)