问题描述
请考虑以下代码段:
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)
计算结果为:
True
False
谁能解释为什么'in'关键字对于集合和列表具有不同的含义?我本来希望两者都返回True,尤其是在要测试的类型定义了相等方法的情况下.
Can anyone explain why the 'in' keyword has a different meaning for sets and lists?I would have expected both to return True, especially when the type being tested has equality methods defined.
推荐答案
含义相同,但实现方式不同.列表仅检查每个对象,检查是否相等,因此它适用于您的类.首先设置对象的哈希值,如果它们不能正确实现哈希值,则该集合似乎无法正常工作.
The meaning is the same, but the implementation is different. Lists simply examine each object, checking for equality, so it works for your class. Sets first hash the objects, and if they don't implement hash properly, the set appears not to work.
您的类定义了__eq__
,但没有定义__hash__
,因此对于集合或作为字典的键将无法正常工作. __eq__
和__hash__
的规则是__eq__
为True的两个对象也必须具有相等的哈希值.默认情况下,对象根据其内存地址进行哈希处理.因此,根据您的定义相等的两个对象不会提供相同的哈希,因此它们违反了有关__eq__
和__hash__
的规则.
Your class defines __eq__
, but doesn't define __hash__
, and so won't work properly for sets or as keys of dictionaries. The rule for __eq__
and __hash__
is that two objects that __eq__
as True must also have equal hashes. By default, objects hash based on their memory address. So your two objects that are equal by your definition don't provide the same hash, so they break the rule about __eq__
and __hash__
.
如果提供__hash__
实现,它将可以正常工作.对于您的示例代码,可能是:
If you provide a __hash__
implementation, it will work fine. For your sample code, it could be:
def __hash__(self):
return hash(self.someattribute)
这篇关于Python 2:集合和列表中'in'关键字的不同含义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!