我正在使用Python的heapq模块来按升序和降序获取数据。
对于升序,我正在使用最小堆,并且以下方法可以正常工作:
>>> from heapq import heapify, heappop
>>> heap = [9, 3, 1, 5, 6, 2, 7]
>>> heapify(heap)
>>> heappop(heap)
1
>>> heappop(heap)
2
>>> heappop(heap)
3
对于降序,我尝试了不同的方法,但它们都有一些缺点:
Using negative value as the priorirty to get reverse sort. I have to use separate list to make data reusable. If the original list is big, having copy of list is costly.
>>> from heapq import heapify, heappop >>> heap = [9, 3, 1, 5, 6, 2, 7] >>> heap_neg = [-x for x in heap] >>> heapify(heap_neg) >>> -heappop(heap_neg) 9 >>> -heappop(heap_neg) 7 >>> -heappop(heap_neg) 6
Using tuple with negative value as priority, this is also waste of space. I would not like to store list of ints as list of tuples.
>>> from heapq import heapify, heappop >>> heap = [(-9, 9), (-3, 3), (-1, 1), (-5, 5), (-6, 6), (-2,2), (-7,7)] >>> heapify(heap) >>> heappop(heap)[1] 9 >>> heappop(heap)[1] 7 >>> heappop(heap)[1] 6
Using key to sort in heapify is missing. Something like:
>>> from heapq import heapify, heappop >>> heap = [9, 3, 1, 5, 6, 2, 7] >>> heapify(heap, key=lambda x:-x) # This doesn't work as heapify don't have key parameter
If I use, heapq._heapify_max(heap), I will have to _heapify_max after each element pop. Like:
>>> from heapq import _heapify_max, heappop >>> heap = [9, 3, 1, 5, 6, 2, 7] >>> _heapify_max(heap) >>> heappop(heap) 9 >>> heappop(heap) # popping without _heapify_max gives wrong result 1 >>> _heapify_max(heap) >>> heappop(heap) # popping after _heapify_max gives correct result 7
heapq.nlargest
(还有heapq.nsmallest
可以执行你第一组代码所做的操作)。当你关心的项目数量远小于原始列表中的项目数量时,这非常高效。 - Blckknghtheapq
的max
特性,那么在_heapify_max(heap)
之后会有一个_heappop_max(heap)
。 - AChampion_heappush_max
,所以使用未记录的函数也是不完美的。 - Blckknght_heapify_max
。你需要在开始时进行一次堆化,否则它就没有堆属性,其他操作也无法按照你的意愿执行。只需进行一次调用(在第一次弹出之前),你就可以得到期望的结果。 - Blckknght