Python 设置交集和 __eq__

标签 python python-2.7 set

根据 this page , set.intersection 使用 __eq__ 方法测试元素是否相等。谁能向我解释为什么这会失败?

>>> Class Foo(object):
>>>     def __eq__(self, other):
>>>         return True
>>>
>>> set([Foo()]).intersection([Foo()])
set([])

使用 2.7.3。是否有另一种(不太复杂)的方法来做到这一点?

最佳答案

如果您覆盖 __eq__,您也应该始终覆盖 __hash__

"If a == b, then it must be the case that hash(a) == hash(b), else sets and dictionaries will fail." Eric

__hash__ 用于从对象中生成整数。 这用于将字典的键或集合的元素放入桶中,以便可以更快地找到它们。

如果您不覆盖 __hash__,尽管对象相等,但默认算法会创建不同的哈希整数。

在你的情况下我会这样做:

class Foo(object):
    def __eq__(self, other):
        return type(self) == type(other)
    def __hash__(self):
        return 1

因为您的类的所有对象都等于该类的所有其他对象,所以它们必须都在集合中的同一个 bucket(1) 中。这样 in 也返回 True

__eq__ 应该是什么样的:

  • 如果你只比较 Foo 对象

    def __eq__(self, other):
        return self.number == other.number
    
  • 如果您还将 Foo 对象与其他对象进行比较:

    def __eq__(self, other):
        return type(self) == type(other) and self.number == other.number
    
  • 如果你有不同的类和不同的相等算法,我推荐 double-dispatch .

    class Foo:
        def __eq__(self, other):
            return hasattr(other, '_equals_foo') and other._equals_foo(self)
        def _equals_foo(self, other):
            return self.number == other.number
        def _equals_bar(self, other):
            return False # Foo never equals Bar
    class Bar:
        def __eq__(self, other):
            return hasattr(other, '_equals_bar') and other._equals_bar(self)
        def _equals_foo(self, other):
            return False # Foo never equals Bar
        def _equals_bar(self, other):
            return True # Bar always equals Bar
    

    这样 a == b 中的 ab 就决定了相等的含义。

关于Python 设置交集和 __eq__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17641604/

相关文章:

python - 如何在 x 轴上绘制带有日期时间的线性回归

algorithm - Matlab分区问题

python - 无法理解 ResNet 的 Identity block 和卷积 block

python - wxPython 弹出通知

python - 如何使用不同版本的 Python 运行 Python Nose 测试

python - Pandas - 将时间戳四舍五入到最接近的秒

python - 用户路径中的 utf-8 字符阻止模块被导入

python - 通过 python 电子邮件发送电子邮件时 HTML 无法正确呈现

Java mockito 模拟集

ios - == 究竟如何与 Set() 一起工作 - Swift