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。
heapq.heappush(h,(3,15))
mnemlml81#
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实现的是最小堆,而不是最大堆。你需要颠倒你的优先顺序,可能是否定它们。
o8x7eapl2#
我发现这篇文章,我试图实现一个固定大小的top-n堆,这里是我可以提供的解决方案:
from heapq import heapify, heappush, heappushpop, nlargest 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)
字符串(感谢@CyanoKobalamyne)
from heapq import heapify, heappush, heappushpop, nlargest 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 nlargest(self.length, self.h)
型
wfsdck303#
如果你想要 k 个最小的元素,这相当于在每次推送时丢弃一个固定大小的最小堆中的最大元素,你应该在你正在构建堆的可迭代对象上使用heapq.nsmallest(或相反的heapq.nlargest)。
heapq.nsmallest
heapq.nlargest
ha5z0ras4#
Python(目前是3.8x版)没有内置的固定堆大小功能。你有两个选择:1.维护一个堆,并在每次推送时检查size > fixedSize是否弹出。这意味着在任何给定的时间,堆的最大大小可能是fixedSize+1,这是你将弹出一个的时候。1.另一种选择是使用heapq.heapreplace(heap, item),根据文档:从堆中弹出并返回最小的项,并推送新项。堆大小不会改变。如果堆为空,则引发IndexError。这个一步操作比heappop()和heappush()更有效,并且在使用固定大小的堆时更合适。
size > fixedSize
fixedSize+1
heapq.heapreplace(heap, item)
66bbxpm55#
我自己也需要这样的东西,一个有最大长度的项目排序列表。我使用了双端队列,因为它的“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)
字符串
1mrurvl16#
要实现有限大小的堆,您可以在每次推送操作后截断堆。
limited_sized_heap = limited_sized_heap[:max_size_of_heap]
字符串这里有一个例子。
import random import heapq max_size_of_heap = 5 limited_sized_heap = [] for i in range(10): a_random = random.randint(1,9) heapq.heappush( limited_sized_heap, a_random ) limited_sized_heap = limited_sized_heap[:max_size_of_heap] print(limited_sized_heap)
型产出:
[3] [3, 9] [3, 9, 4] [3, 4, 4, 9] [2, 3, 4, 9, 4] [1, 3, 2, 9, 4] [1, 3, 1, 9, 4] [1, 3, 1, 9, 4] [1, 3, 1, 9, 4] [1, 3, 1, 9, 4]
型如果你需要绝对固定大小的堆,而不是有限大小的堆,你可以只使用具有无限值的固定大小的列表来初始化堆。
fixed_sized_heap = [float('inf')] * heap_size
fwzugrvs7#
heapq中没有内置的函数来检查大小,所以你必须自己做:
if len(h) < capacity: heapq.heappush(h, thing) else: # pushes the element on and then pops off the top heapq.heappushpop(h, thing)
字符串请注意,heapq实现了一个最小堆,而不是最大堆。你需要颠倒你的优先顺序我看到你在你的帖子中特别提到你想要一个固定大小为3的最大堆,并且在添加新元素时能够保持最小的元素。通过在插入min堆时对元素取反,您将能够利用堆弹出。您现在将删除最大的元素并替换它,而不是删除最小的元素并替换它这样做的缺点是,当你弹出元素时,你会看到它们的大小顺序是相反的。所以如果你想要一个正确的升序列表,你就必须否定它们并颠倒它们的顺序下面是一个例子:A visualization of pushpop when using the default minheap vs when negating the elements of the minheapHere's an example of how it's implemented in a specific problem with the same requirements outlined in your post的
7条答案
按热度按时间mnemlml81#
heapq中没有内置的方法来检查大小,所以你必须自己做:
字符串
另外,请注意,heapq实现的是最小堆,而不是最大堆。你需要颠倒你的优先顺序,可能是否定它们。
o8x7eapl2#
我发现这篇文章,我试图实现一个固定大小的top-n堆,这里是我可以提供的解决方案:
字符串
(感谢@CyanoKobalamyne)
型
wfsdck303#
如果你想要 k 个最小的元素,这相当于在每次推送时丢弃一个固定大小的最小堆中的最大元素,你应该在你正在构建堆的可迭代对象上使用
heapq.nsmallest
(或相反的heapq.nlargest
)。ha5z0ras4#
Python(目前是3.8x版)没有内置的固定堆大小功能。你有两个选择:
1.维护一个堆,并在每次推送时检查
size > fixedSize
是否弹出。这意味着在任何给定的时间,堆的最大大小可能是fixedSize+1
,这是你将弹出一个的时候。1.另一种选择是使用
heapq.heapreplace(heap, item)
,根据文档:从堆中弹出并返回最小的项,并推送新项。堆大小不会改变。如果堆为空,则引发IndexError。这个一步操作比heappop()和heappush()更有效,并且在使用固定大小的堆时更合适。
66bbxpm55#
我自己也需要这样的东西,一个有最大长度的项目排序列表。
我使用了双端队列,因为它的“maxlen”属性。
字符串
1mrurvl16#
要实现有限大小的堆,您可以在每次推送操作后截断堆。
字符串
这里有一个例子。
型
产出:
型
如果你需要绝对固定大小的堆,而不是有限大小的堆,你可以只使用具有无限值的固定大小的列表来初始化堆。
型
fwzugrvs7#
heapq中没有内置的函数来检查大小,所以你必须自己做:
字符串
请注意,heapq实现了一个最小堆,而不是最大堆。你需要颠倒你的优先顺序
我看到你在你的帖子中特别提到你想要一个固定大小为3的最大堆,并且在添加新元素时能够保持最小的元素。
通过在插入min堆时对元素取反,您将能够利用堆弹出。您现在将删除最大的元素并替换它,而不是删除最小的元素并替换它
这样做的缺点是,当你弹出元素时,你会看到它们的大小顺序是相反的。所以如果你想要一个正确的升序列表,你就必须否定它们并颠倒它们的顺序
下面是一个例子:
A visualization of pushpop when using the default minheap vs when negating the elements of the minheap
Here's an example of how it's implemented in a specific problem with the same requirements outlined in your post的