python - 为什么给字典的键 `True` 赋值会覆盖同一字典中键 `1` 的值?

标签 python dictionary key hashtable hash-collision

对于这个简单的字典——

键 1 和值“apple”总是打印为“1: False”

是否有我忽略的原因?

$ cat 字典.py

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

*$ python3.8 dict.py

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

谢谢

最佳答案

Python 中的 bool 类型是 int 的子类型,其中 True 等于数字 1False 等于数字 0:

>>> True == 1
True
>>> False == 0
True

当值被散列时,它们也分别产生相同的值:

>>> hash(True)
1
>>> hash(1)
1
>>> hash(False)
0
>>> hash(0)
0

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

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

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

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

关于python - 为什么给字典的键 `True` 赋值会覆盖同一字典中键 `1` 的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64522934/

相关文章:

python - 使用 Python 更改网格厚度的极坐标图

c# - 您可以在自己的初始化行中使用变量(字典中的 tryGetOrElse)吗?

mysql - 错误: Error 1215: Cannot add foreign key constraint even when both fields are of the same type

php - 使用不带引号的数组键,如何在大项目中修复它?

audio - 如何禁用Windows CE中的按键声音?

python - PySCIPOpt 经常被段错误 (SIGSEGV) 中断

python - 删除 python 字典中具有 nan 值的条目

python - 在Caffe中训练GoogLeNet时如何向输入图像添加外部特征?

python - pyhamcrest 包含字典列表的匹配器

python - 检查字典内字典内列表的值