Python字典的奇怪行为

3

我在学习Python哈希函数时,遇到了以下行为。

>>> hash(-1)
-2
>>> hash(-2)
-2

已经有一篇很优秀的 Stack Overflow 帖子回答了为什么 -1 和 -2 都会哈希成 -2: Why do -1 and -2 both hash to -2 in CPython?

由于 Python 字典使用键的哈希值来存储值,因此以下输出是预期的,因为 True1 均具有相同的哈希值:

>>> my_dict = { True: "true", 1: "one"}
>>> my_dict
{True: 'one'}
>>> hash(True)
1
>>> hash(1)
1

但是如果我用以下代码尝试,我期望输出结果为{ -1: "Minus Two"},因为-1-2具有相同的哈希值。但实际情况并非如此。

>>> my_dict = { -1: "Minus One", -2: "Minus Two"}
>>> my_dict
{-1: 'Minus One', -2: 'Minus Two'}
>>> hash(-1)
-2
>>> hash(-2)
-2

这种行为的原因是什么?难道字典不使用键的哈希值来存储它的值吗?
注意:我知道这是特定于CPython的,但我很想知道这种行为的原因。

如果它只使用哈希值,那么它完全没有用对吧?你不能自信地将任何东西存储在其中,因为你不能确保它们具有不同的哈希值。是的,它使用哈希值,但如果哈希值相同还会检查相等性。 - Sraw
顺便说一句,这不是特定于CPython的,所有哈希字典都有类似的实现。您看到此行为的唯一原因只是因为在CPython中1 == True - Sraw
1
由于Python字典使用键的哈希值来存储值,因此预期会输出以下内容,因为True和1都具有相同的哈希值。但是,仅凭这个事实本身并不意味着两者都必须一致,哈希值和相等性都必须保持一致。 - juanpa.arrivillaga
1个回答

3

它不仅检查对象的哈希值,还检查它的相等性。您可以通过以下示例看到其效果:

>>> class Samesies:
...     def __hash__(self):
...             return 1
...     def __eq__(self, other):
...             return True
...
>>> {Samesies(): 1, Samesies(): 2}
{<__main__.Samesies object at 0x0000023997ACEFA0>: 2}

编辑: 1 == Truehash(1) == hash(True) 的原因是因为 bool 实际上是 int 的子类。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接