Hash tables are supposed be high-performance mappings,and because Python dicts are implemented with hash tables,他们的表现也非常出色。但是在查看负整数的哈希值时,我遇到了一个奇怪的结果。
>>> for i in range(7):
... print hash(i-4)
...
-4
-3
-2
-2
0
1
2
但这显然对dicts没有影响:
>>> d = dict()
>>> d[-1] = 'foo'
>>> d[-2] = 'bar'
>>> d
{-2: 'bar', -1: 'foo'}
为什么会发生这种情况,为什么我使用时不会影响dicts?
答案 0 :(得分:3)
x
哈希值与y
不同的事实意味着x != y
。但反过来却不是真的!因此,当x
的哈希值等于y
时,仍会明确检查它们是否相等。
在哈希函数的上下文中hash(x) == hash(y)
和x != y
被称为 collision 的情况,并且可能会不时发生。你想尽可能地避免它,但总的来说它是不可避免的。您可以阅读有关散列函数和碰撞的更多信息here。
答案 1 :(得分:1)
如果您问为什么dicts不受重复哈希值的影响,那是因为哈希值不需要唯一的哈希表才能工作。
Python实现整数的简单散列,其中整数的散列值解析为自身。由于-1在内部用于指示失败以产生散列值,因此值-1默默地替换为-2,这也适用。
答案 2 :(得分:1)
-1
是C代码中的错误代码,没有散列函数可以返回它,以免它发出C代码错误信号。 C没有异常,因此Python开发人员必须保留一个返回值以表示错误。
字典没有使用 哈希;它还测试平等。请注意,哈希表 small 与可能的哈希值的数量相比,即使哈希值不相等,它们仍然可以最终映射到同一个槽。如果哈希值映射到同一个槽并且密钥不相等,则扰乱哈希并找到新的槽。
因为-1 != -2
,Python仍然保持两个键分开。
有关Python字典如何使用哈希值的详细信息,请参阅Overriding Python's Hashing Function in Dictionary和Why is the order in dictionaries and sets arbitrary?。
答案 3 :(得分:1)
哈希表在哈希值不同时表现更好,但是它们可以处理相同的哈希值。这些被称为哈希冲突,处理它们的方法是优化和调整哈希表的重要方法之一。
hash(-1) == -2
因为-1是一个特殊值,用于表示C实现中的错误。哈希码不能取该值;如果你试图定义一个给出散列值-1的类,Python会检测它并使用-2代替。