我最近遇到了
python 2.7的问题:
class A(object):
def __init__(self, v):
self.v = v
def __eq__(self, other):
return self.v == other.v
a1 = A(1)
a2 = A(1)
所以:
print a1 == a2 # True
和:
d = {a1: 1}
print a2 in d.keys() # True
但:
print a2 in d # False
问题是a2 ind.keys()和d中的a2之间的主要区别是什么?我怎样才能获得d中的a2是真的?
最佳答案 在Python 2.7中,dict.keys返回一个键列表,而d.keys()中的a2将线性迭代所有键,以查找a2是否在列表中.
但是d中的a2将只是在字典中基于对象a2的哈希值进行O(1)查找,以查看密钥a2是否在d中.
但在你的情况下,问题完全不同.引用official documentation,
If a class does not define a
__cmp__()
or__eq__()
method it should not define a__hash__()
operation either; if it defines__cmp__()
or__eq__()
but not__hash__()
, its instances will not be usable in hashed collections. If a class defines mutable objects and implements a__cmp__()
or__eq__()
method, it should not implement__hash__()
, since hashable collection implementations require that a object’s hash value is immutable (if the object’s hash value changes, it will be in the wrong hash bucket).
由于您没有明确定义__hash__函数,因此您打破了它们之间的契约,__ hash__使用基于对象id
的默认散列,对于a1和a2都是不同的.因此,即使a1和a2相似,哈希对象也会将它们视为两个不同的对象,因为它们的哈希值不同.
要解决这个问题,你需要定义__hash__函数,就像这样
class A(object):
def __init__(self, v):
self.v = v
def __eq__(self, other):
return self.v == other.v
def __hash__(self):
return hash(self.v)
a1 = A(1)
a2 = A(1)
d = {a1: 1}
print a2 in d.keys() # True
print a2 in d # True