[英]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
返回一個鍵列表,而a2 in d.keys()
將線性迭代所有鍵,以查找a2
是否在列表中。
但是a2 in d
將只是在字典中基於對象a2
的哈希值進行O(1)查找,以查看密鑰a2
是否在d
。
但在你的情況下,問題完全不同。 引用官方文檔 ,
如果類沒有定義
__cmp__()
或__eq__()
方法,它也不應該定義__hash__()
操作; 如果它定義__cmp__()
或__eq__()
但不__hash__()
,則它的實例將不能在散列集合中使用。 如果一個類定義了可變對象並實現了__cmp__()
或__eq__()
方法,則它不應該實現__hash__()
,因為hashable collection實現要求對象的哈希值是不可變的(如果對象的哈希值發生變化,它將在錯誤的哈希桶)。
由於您沒有明確定義__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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.