为什么将值分配给字典的键“True”会覆盖同一字典中键“1”的值?

Jak*_*ope 3 python dictionary hashtable key hash-collision

对于这个简单的字典 -

Key 1 和 Value "apple" 总是打印为 "1: False"

有没有我忽略的原因?

$ cat dict.py

pairs = {1: "apple",
    "orange": [2, 3, 4], 
    True: False, 
    None: "True",
}
print(pairs)

Run Code Online (Sandbox Code Playgroud)

* $ python3.8 dict.py

{1: False, 'orange': [2, 3, 4], None: 'True'}

Run Code Online (Sandbox Code Playgroud)

谢谢

pok*_*oke 5

bool在Python类型是其亚型int,其中True等于数1False等于数0

>>> True == 1
True
>>> False == 0
True
Run Code Online (Sandbox Code Playgroud)

当这些值被散列时,它们也会产生各自相同的值:

>>> hash(True)
1
>>> hash(1)
1
>>> hash(False)
0
>>> hash(0)
0
Run Code Online (Sandbox Code Playgroud)

现在,由于字典键基于散列和对象相等(首先使用散列相等来快速找到可能相等的键,然后通过相等来比较它们),导致相同散列且相等的两个值将导致相同字典的“槽”。

如果您创建一个也具有此行为的自定义类型,您也可以看到这一点:

>>> class CustomTrue:
        def __hash__(self):
            return 1
        def __eq__(self, other):
            return other == 1

>>> pairs = {
        1: "apple",
        "orange": [2, 3, 4], 
        True: False, 
        None: "True",
    }
>>> pairs[CustomTrue()] = 'CustomTrue overwrites the value'
>>> pairs
{1: 'CustomTrue overwrites the value', 'orange': [2, 3, 4], None: 'True'}
Run Code Online (Sandbox Code Playgroud)

虽然这解释了这种行为,但我同意它可能有点令人困惑。因此,我建议不要使用不同类型的字典键,以免遇到这种情况。