如果我写:
d = { 0:'a', 1:'b' }
d[False] = 'c'
d[True] = 'd'
print(d)
我得到:
{ 0:'c', 1:'d' }
为什么将它们强制转换为整数?它反过来做同样的事情。
d = {False:'a', True:'b'}
d[0] = 'c'
d[1] = 'd'
print(d)
输出是:
{False:'c', True: 'd'}
这可以禁用吗?它是一个错误吗?
如果我写:
d = { 0:'a', 1:'b' }
d[False] = 'c'
d[True] = 'd'
print(d)
我得到:
{ 0:'c', 1:'d' }
为什么将它们强制转换为整数?它反过来做同样的事情。
d = {False:'a', True:'b'}
d[0] = 'c'
d[1] = 'd'
print(d)
输出是:
{False:'c', True: 'd'}
这可以禁用吗?它是一个错误吗?
只是提供一些关于 arshajii 答案的背景。
两个布尔值True
和False
与整数有着奇怪的关系。
一方面,它们具有不同的字符串表示形式,并且具有不同的身份:
>>> print(True)
True
>>> print(1)
1
>>> True is 1
False
另一方面,它们在比较和算术中表现为整数:
>>> True == 1
True
>>> True + 1
2
这种行为的原因是兼容性。很久以前,这种bool
类型不存在。“布尔”运算符复制了 C 的行为,重用了“假”0
和1
“真”。
最终 Guido 意识到这没有多大意义,并添加了我们知道和喜爱的常量。
但有一个问题。即便如此,已经有很多代码将布尔值处理为整数。如果布尔运算开始使用“正确”类型,那么所有这些代码都会中断。
所以Guido做出了妥协。布尔值有自己的类型,bool
,并且显示方式与整数不同。但是在算术运算和比较中,最值得注意的是__eq__
和__hash__
,它们被视为一回事。所以旧代码将继续工作,而新代码仍然可以利用新bool
类型。
也许这会在 Python 4 中改变。但现在,bool
是 的子类int
,我们将不得不忍受它。
(在相关的说明中,这就是为什么True
andFalse
是 Title Case,而不是像其他 Python 关键字那样小写的原因之一。)
这是因为这些值被认为是相等的:
>>> True == 1
True
>>>
>>> False == 0
True
并具有相同的哈希值:
>>> hash(True), hash(1)
(1, 1)
>>>
>>> hash(False), hash(0)
(0, 0)
因此,从字典的角度来看,True
和1
是无法区分False
的0
。
没有办法“禁用”它——你不应该在字典中使用非同质键。
在这种特定情况下,一种潜在的解决方法是分别为True
和False
以外的1
和保留特殊的 int 值0
(假设您需要1
和0
作为独立键)。例如,您可以使用-1
代表True
和-2
代表False
。
bool
是int
其表示为“False”或“True”的子类,但其值为0 或 1。