我有两个代表相同的对象。我甚至投保他们有相同的哈希。我仍然从字典中得到错误:
>>> hash(one)
1098414562
>>> hash(one+zero)
1098414562
>>> a={one:1}
>>> a[one+zero]
Traceback (most recent call last):
File "<pyshell#25>", line 1, in <module>
a[one+zero]
KeyError: {{|}|}
我还需要做些什么来确保字典将其重新组合为同一个密钥?
答案 0 :(得分:2)
如果某个类未定义
__cmp__()
或__eq__()
方法,则不应定义__hash__()
操作;如果它定义__cmp__()
或__eq__()
但不定义__hash__()
,则其实例将无法在散列集合中使用。如果一个类定义了可变对象并实现了__cmp__()
或__eq__()
方法,那么它不应该实现__hash__()
,因为hashable collection实现要求对象的哈希值是不可变的(如果对象的哈希值)更改,它将在错误的哈希桶中。)
答案 1 :(得分:2)
要正确hashable dict键,对象还必须定义__eq__()
或__cmp__()
。它们必须比较等于被识别为相同的密钥。
如果对象具有相同的哈希值,但不比较相等,则假定哈希冲突,并且它们分别在同一个哈希桶中。
当通过散列查找对象时,匹配的散列桶中的所有对象都会与它进行比较,如果没有相等,那就是KeyError。
答案 2 :(得分:0)
这称为哈希冲突。哈希只是在字典中分发密钥的一种相对有效的方法。它不保证唯一性。当您查找某个键时,需要考虑具有匹配哈希的所有键,并使用__eq__
方法确定它们是否真的匹配。
除了:
有一个类总是为它的任何实例返回相同的哈希值。然而,这会破坏通常的O(1)
查找复杂性
您可以通过在此处尝试n
的不同值
class MyInt(int):
def __hash__(self):
return hash(1)
d = {MyInt(i): i for i in xrange(n)}
d[MyInt(1)] # This will take O(n) time since all values have the same hash