2013-07-01 72 views
1

我有两个对象代表相同的一个。我甚至保证他们有相同的散列。我仍然有一个错误,虽然从字典:对象具有相同的散列,字典没有识别为相同的

>>> 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: {{|}|} 

还有什么我必须做,以确保字典reconizes它作为相同的密钥?

回答

2

要正确hashable字典键,对象还必须定义__eq__()__cmp__()。它们必须相等才能被认为是同一把钥匙。

如果对象具有相同的哈希值,但不相等,则假定哈希碰撞,并且它们分别位于相同的哈希桶中。

当通过哈希查找对象时,将匹配哈希桶中的所有对象与它进行比较,如果不相等,则为KeyError。

+2

我忘了return语句在我的'__eq__'试验破坏了平常O(1)查找复杂

你可以很容易地看到线性时间查找。 – PyRulez

+1

哎呀,那可能是一个棘手的错误找到 –

2

如果一个类不定义__cmp__()__eq__()方法不应该限定__hash__()操作要么;如果它定义了__cmp__()__eq__()而不是__hash__(),则其实例在散列集合中将不可用。如果一个类定义了可变对象并实现了__cmp__()__eq__()方法,则它不应该实现__hash__(),因为可哈希集合实现要求对象的哈希值是不可变的(如果对象的哈希值更改,它将位于错误哈希桶中)。

source

0

这被称为散列冲突。散列只是在字典中分配密钥的一种相对有效的方式。它不保证唯一性。在查找密钥时,需要考虑所有带有匹配哈希的密钥,并使用__eq__方法确定它们是否匹配。

除此之外: 可能有一个类总是为它的任何实例返回相同的散列。然而,这通过与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 
相关问题