【问题标题】:How do I make my class comparable in Python?如何使我的课程在 Python 中具有可比性?
【发布时间】:2020-06-20 08:37:13
【问题描述】:

我有一个 Pair 类(它有一个键和一个值),我正在尝试制作一个程序来创建一堆 Pair 对象,将它们添加到列表中,并执行 稳定的快速排序 在他们身上。但是,我似乎不知道如何使对象具有可比性,以便程序在两个对象具有相同值时自动比较它们的键。在 Java 中很容易做到这一点,但我只是不明白我应该如何在 Python 中做到这一点。

提前谢谢你!

class Pair(Generic[K,V]):
    def __init__(self, key: K, val: V):
        self.key = key
        self.value = val

【问题讨论】:

标签: python oop quicksort comparable keyvaluepair


【解决方案1】:

以下内容如何(可按键排序,但您可以轻松定义任何其他方式对它们进行排序):

class Pair:
    def __init__(self, key, val):
        self.key = key
        self.value = val

    def __eq__(self, other: "Pair"):
        return self.key == other.key

    def __lt__(self, other: "Pair"):
        return self.key < other.key

    def __le__(self, other: "Pair"):
        return self.key <= other.key

    def __gt__(self, other: "Pair"):
        return self.key > other.key

    def __ge__(self, other: "Pair"):
        return self.key >= other.key

    def __str__(self):
        return f"{self.key}={self.value}"

    def __repr__(self):
        return f"{self.key}={self.value} ({id(self)})"


test = [
    Pair("a2", "1"), Pair("a1", "2"), Pair("b1", "3"),Pair("br", "4")
]

print(sorted(test))

输出:

$ python3 ~/tmp/test.py
[a1=2 (4352627216), a2=1 (4352622288), b1=3 (4352627344), br=4 (4352627408)]

要按值排序,然后在值相等时按键排序,您将 dp 类似:

    def __lt__(self, other: "Pair"):
        if self.value != other.value:
            return self.value < other.value

        return self.key < other.key

上面lt的示例输入/输出:

# Input
test = [
    Pair("a2", "1"), Pair("a1", "2"), Pair("b1", "1"),Pair("br", "4")
]

# Output
[a2=1 (4466773648), b1=1 (4466778768), a1=2 (4466778640), br=4 (4466778832)]

此外,如果您计划将这些对用作字典键或集合,您可以实现__hash__。更多运营商见here

【讨论】:

  • 非常感谢!这真的很彻底,真的很有帮助
  • 另外,如果值仅在 __lt__ 方法中相同,而在其他任何地方都没有,为什么要区分比较键?
  • @user11610667 这个想法是向您展示您可以覆盖的最重要的方法。我只实现了__lt__ 作为示例,但在其余部分中应该直接执行此操作(这也是用于排序的)
  • 啊,我明白了。你能告诉我最后两种方法是什么(str&repr)吗?我想我以前没见过他们
  • @user11610667 它们都用于将对象转换为字符串。大多数情况下,这是打印所需要的。然而,str 的目标是使对象可读,而repr 更专注于生成对象的唯一表示(因此它的 python id() 和类也可能出现)。在日志记录和调试方面都非常有用 - 阅读更多 here
【解决方案2】:

Python 为此使用了所谓的“dunder 方法”(双下划线方法)。您已经在使用 init dunder 方法。定义__eq__

编辑:见优秀dbader article

【讨论】:

    猜你喜欢
    • 2016-10-18
    • 2017-04-11
    • 1970-01-01
    • 2011-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多