Python 2:集合和列表的'in'关键字的不同含义

msk*_*kel 8 python equality list set

请考虑以下代码段:

class SomeClass(object):

    def __init__(self, someattribute="somevalue"):
        self.someattribute = someattribute

    def __eq__(self, other):
        return self.someattribute == other.someattribute

    def __ne__(self, other):
        return not self.__eq__(other)

list_of_objects = [SomeClass()]
print(SomeClass() in list_of_objects)

set_of_objects = set([SomeClass()])
print(SomeClass() in set_of_objects)
Run Code Online (Sandbox Code Playgroud)

其评估结果为:

True
False
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释为什么'in'关键字对集合和列表有不同的含义?我本来希望两者都返回True,特别是当被测试的类型定义了相等的方法时.

Ned*_*der 16

含义相同,但实施方式不同.列表只是检查每个对象,检查是否相等,因此它适用于您的类.设置对象的第一个哈希值,如果它们没有正确实现哈希,则该集合似乎不起作用.

您的类定义__eq__但未定义__hash__,因此无法正确设置集或作为字典的键.为治__eq____hash__是两个对象__eq__为真也必须具有相同的哈希值.默认情况下,对象根据其内存地址进行哈希.因此,您定义的两个对象不会提供相同的哈希值,因此它们违反了规则__eq____hash__.

如果您提供__hash__实现,它将正常工作.对于您的示例代码,它可能是:

def __hash__(self):
    return hash(self.someattribute)
Run Code Online (Sandbox Code Playgroud)

  • 这是Python 3更清楚地处理的事情之一:它将拒绝从没有`__hash __()`的任何对象中创建一个集合.Python 2有一个默认的`__hash __()`,它反映了对象的身份而不是相等. (4认同)