字典中的键和 dict.keys() 中的键有什么区别?
What are the differences between key in dict & key in dict.keys()?
我最近遇到 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()
和 a2 in d
之间的主要区别是什么?我怎样才能得到a2 in d is True
?
在 Python 2.7 中,dict.keys
returns 键列表和 a2 in d.keys()
将线性迭代所有键以查找 a2
是否在列表。
但是 a2 in d
会根据对象 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
我最近遇到 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()
和 a2 in d
之间的主要区别是什么?我怎样才能得到a2 in d is True
?
在 Python 2.7 中,dict.keys
returns 键列表和 a2 in d.keys()
将线性迭代所有键以查找 a2
是否在列表。
但是 a2 in d
会根据对象 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