【问题标题】:How to invert the order of elements in a heapq heap with object comparison functions?如何使用对象比较函数反转 heapq 堆中元素的顺序?
【发布时间】:2018-11-23 16:23:27
【问题描述】:

首先,我阅读了这个SO question,但它实际上并没有包含我想要的方法。此外,否定实际值不适用于我的用例。

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)

现在我想要一个倒序。因此,我将return self.a &lt; other.a 更改为return self.a &gt; 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)

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

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) 

可能不是所有的对象对都由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)

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

【问题讨论】:

    标签: python python-3.x heap python-3.6


    【解决方案1】:

    你需要使用heapifyl变成一个堆

    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))
    

    打印

    C(a=9, b=4)
    C(a=9, b=109)
    C(a=2, b=1)
    C(a=2, b=4)
    

    【讨论】:

    • 但是为什么它在第一种情况下有效(在我的问题中)?该列表未排序。
    • 因为您的示例列表恰好在 &lt; 未反转时满足堆不变量,但在 &lt; 反转时不是有效堆。 Theory section of the heapq documentation 是开始阅读的好地方,但我也建议您实际尝试实现所有功能以了解它们的工作原理。
    猜你喜欢
    • 1970-01-01
    • 2021-12-24
    • 2021-09-19
    • 1970-01-01
    • 2017-04-09
    • 2014-11-02
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多