对象具有相同的散列,字典不能识别为相同

时间:2013-07-01 00:24:00

标签: python dictionary hashtable

我有两个代表相同的对象。我甚至投保他们有相同的哈希。我仍然从字典中得到错误:

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

我还需要做些什么来确保字典将其重新组合为同一个密钥?

3 个答案:

答案 0 :(得分:2)

  

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

source

答案 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
相关问题