如何使用对象比较函数反转 heapq 堆中元素的顺序?

d4r*_*rty 2 python heap python-3.x python-3.6

首先,我读了这个问题,但它实际上不包括我想要的方法。此外,否定实际值不适用于我的用例。

Heapq 文档:https://docs.python.org/3.6/library/heapq.html

假设我的堆中有一个数据类对象列表。只有a属性决定对象的顺序。

import heapq
from dataclasses import dataclass

@dataclass
class C:
    a: int
    b: int
    def __lt__(self, other):
        return self.a < other.a

l=[C(2,1),C(9,109),C(2,4),C(9,4)]

print(heapq.heappop(l)) # C(a=2, b=1)
print(heapq.heappop(l)) # C(a=2, b=4)
print(heapq.heappop(l)) # C(a=9, b=109)
print(heapq.heappop(l)) # C(a=9, b=4)
Run Code Online (Sandbox Code Playgroud)

现在我想要一个倒序。因此,我将该行更改return self.a < other.areturn self.a > other.a. 结果:

import heapq
from dataclasses import dataclass

@dataclass
class C:
    a: int
    b: int
    def __lt__(self, other):
        return self.a > other.a

l=[C(2,1),C(9,109),C(2,4),C(9,4)]

print(heapq.heappop(l)) # C(a=2, b=1)
print(heapq.heappop(l)) # C(a=9, b=109)
print(heapq.heappop(l)) # C(a=9, b=4)
print(heapq.heappop(l)) # C(a=2, b=4)
Run Code Online (Sandbox Code Playgroud)

期望的结果应该是以下四种解决方案之一:

C(a=9, b=109)   C(a=9, b=4)      C(a=9, b=109)  C(a=9, b=4)    
 C(a=9, b=4)    C(a=9, b=109)    C(a=9, b=4)    C(a=9, b=109) 
 C(a=2, b=1)    C(a=2, b=1)      C(a=2, b=4)    C(a=2, b=4)  
 C(a=2, b=4)    C(a=2, b=4)      C(a=2, b=1)    C(a=2, b=1) 
Run Code Online (Sandbox Code Playgroud)

也许,并不是所有的物体对都heapq可以通过比较来解释奇怪的顺序。但是,是否仍然可以获得倒序?

我是否必须提供更多对象比较方法?

object.__lt__(self, other)
object.__le__(self, other)
object.__eq__(self, other)
object.__ne__(self, other)
object.__gt__(self, other)
object.__ge__(self, other)
Run Code Online (Sandbox Code Playgroud)

如果您有完全不同的方法,请不要犹豫!

Pat*_*ugh 5

你需要l使用heapify

from heapq import heapify, heappop
from dataclasses import dataclass

@dataclass
class C:
    a: int
    b: int
    def __lt__(self, other):
        return self.a > other.a

l=[C(2,1),C(9,109),C(2,4),C(9,4)]

heapify(l)    

while l:
    print(heappop(l))
Run Code Online (Sandbox Code Playgroud)

印刷

C(a=9, b=4)
C(a=9, b=109)
C(a=2, b=1)
C(a=2, b=4)
Run Code Online (Sandbox Code Playgroud)