【问题标题】:Objects have same hash, dictionary not recognizing as same对象具有相同的哈希,字典不识别为相同
【发布时间】:2013-06-28 01:53:15
【问题描述】:
我有两个对象代表同一个对象。我什至保证他们有相同的哈希值。我仍然从字典中得到一个错误:
>>> 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: {{|}|}
我还需要做什么来确保字典将其重新识别为相同的键?
【问题讨论】:
标签:
python
dictionary
hashtable
【解决方案1】:
要正确地成为hashable dict 键,对象还必须定义__eq__() 或__cmp__()。它们必须比较相等才能被识别为相同的键。
如果对象具有相同的哈希,但比较不相等,则假设哈希冲突,并且它们在同一个哈希桶中分开。
当通过hash查找对象时,匹配的hash桶中的所有对象都与它进行比较,如果没有相等,则为KeyError。
【解决方案2】:
如果一个类没有定义__cmp__() 或__eq__() 方法,它也不应该定义__hash__() 操作;如果它定义了__cmp__() 或__eq__() 而不是__hash__(),则它的实例将无法在散列集合中使用。如果一个类定义了可变对象并实现了__cmp__()或__eq__()方法,它不应该实现__hash__(),因为可哈希集合实现要求对象的哈希值是不可变的(如果对象的哈希值发生变化,它将在错误的哈希桶)。
source
【解决方案3】:
这称为哈希冲突。散列只是在字典中分配键的一种相对有效的方式。它不保证唯一性。当你查找一个key时,需要考虑所有具有匹配hash的key,并会使用__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