为什么CPython Dicts不会受到负值1和负值2的哈希值的影响

时间:2013-11-22 22:55:08

标签: python dictionary hash language-implementation python-internals

Hash tables are supposed be high-performance mappingsand 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?

4 个答案:

答案 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 DictionaryWhy is the order in dictionaries and sets arbitrary?

答案 3 :(得分:1)

哈希表在哈希值不同时表现更好,但是它们可以处理相同的哈希值。这些被称为哈希冲突,处理它们的方法是优化和调整哈希表的重要方法之一。

hash(-1) == -2因为-1是一个特殊值,用于表示C实现中的错误。哈希码不能取该值;如果你试图定义一个给出散列值-1的类,Python会检测它并使用-2代替。