2

哈希表应该是高性能的映射并且因为 Python dicts 是用哈希表实现的,所以它们也是高性能的。但是在查看负整数的哈希值时,我遇到了一个奇怪的结果。

>>> 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

4 回答 4

3

x具有不同哈希值的事实y意味着x != y. 但反之则不然!因此,当x哈希值等于时,y仍然会明确检查它们是否相等。

hash(x) == hash(y)在散列函数的上下文中x != y称为冲突的情况是可能不时发生的事情。你想尽可能地避免它,但总的来说这是不可避免的。您可以在此处阅读有关散列函数和冲突的更多信息。

于 2013-11-22T22:59:45.993 回答
1

如果您问为什么 dicts 不受重复哈希值的影响,那是因为哈希值不需要是唯一的哈希表才能工作。

Python 实现了整数的简单散列,其中整数的散列值解析为自身。由于 -1 在内部用于表示生成哈希值失败,因此值 -1 会被 -2 静默替换,这同样有效。

于 2013-11-22T22:58:48.663 回答
1

-1是 C 代码中的错误代码,并且没有哈希函数可以返回它,以免它指示 C 代码错误。C 没有异常,因此 Python 开发人员必须保留一个返回值来发出错误信号。

字典不只使用散列;它还测试是否相等。请注意,与可能的哈希值的数量相比,哈希表很小,即使哈希值相等,它们仍然可以最终映射到同一个槽。如果哈希值映射到同一个槽并且键不相等,则哈希受到扰动并找到新槽。

因为-1 != -2,Python 仍然将两个键分开。

请参阅在字典中覆盖 Python 的散列函数为什么字典和集合中的顺序是任意的?有关 Python 字典如何使用哈希的更多详细信息。

于 2013-11-22T22:58:51.850 回答
1

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

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

于 2013-11-22T23:00:28.333 回答