使用真/假作为键 - 这是如何/为什么工作的?

15 投票
3 回答
23568 浏览
提问于 2025-04-17 21:27

我习惯用这种简单的语法来初始化一个 字典

d = {'a':'Apple','b':'Bat'};

今天,在浏览一个页面时,我遇到了一段奇怪的代码。

{True:0, False:1}[True];

我在想,这段代码为什么/怎么能工作呢? TrueFalse 是保留关键字,所以那种奇怪的语法对编译器来说应该是没有意义的,但实际上并不是。

>>> d = {True:0, False:1};
>>> d
{False: 1, True: 0}

而且这事情还变得更奇怪了。

>>> d = dict(True = 0, False = 1);
SyntaxError: assignment to keyword
>>> d = dict(_True = 0, _False = 1);
>>> d
{'_False': 1, '_True': 0}

dict() 构造函数中,True 这个关键字是不被允许的!但是……


更新

Python 3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:03:43) [MSC v.1600 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import keyword
>>> keyword.iskeyword('print');
False
>>> keyword.iskeyword('else');
True
>>> keyword.iskeyword('True');
True
>>> keyword.iskeyword('False');
True

3 个回答

2

TrueFalse 不是关键字,它们实际上是对象。你可以在 Python 解释器中验证这一点(这里使用的是 2.7 版本,但在 3.x 版本中也是一样的):

Python 2.7.6 (default, Jan 29 2014, 21:22:07) 
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.79)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> type(True)
<type 'bool'>
>>> True.__class__.__name__
'bool'
>>> type(False)
<type 'bool'>
>>> False.__class__.__name__
'bool'
>>> hash(True)
1
>>> hash(False)
0
>>> True.__hash__
<method-wrapper '__hash__' of bool object at 0x100134da0>
>>> False.__hash__
<method-wrapper '__hash__' of bool object at 0x100134db8>

所以它们可以用作字典或类似结构中的键。

事实上,在 Python 3 之前,你可以把 TrueFalse 当作参数名来使用 dict()

>>> d = dict(True="true", False="false")
>>> d
{'False': 'false', 'True': 'true'}

不过,为了避免混淆,Python 3 的解释器不允许这样做,因为它现在基本上把它们当作关键字来处理——但实际上,它们仍然是对象。(可以说它们有点像两者的结合。)

4

为什么它应该是没有意义的呢?TrueFalse 是值,不是关键字。这就是为什么你可以用它们来比较其他值。

你在创建字典的时候也不能用整数。这是关键字参数的限制,而不是字典本身的限制。

15

虽然在Python 3中,TrueFalse是关键词,但它们其实也是对象的名字(分别对应bool(1)bool(0))。

所以你可以在任何需要值的地方使用它们。因为它们是可哈希的,所以也可以用作字典的键。你可以这样做:

d = {}
d[True] = "True"
d[False] = "False"

你也可以直接用大括号来创建同样的字典(d = {True: "True", False: "False"}),但如果使用dict构造函数和关键词参数就不行。构造函数的关键词版本只能创建键是字符串的字典,而这些字符串必须是合法的Python标识符。TrueFalse不是字符串,而且由于它们是关键词,所以也不能用作标识符。

当然,如果你有某种原因需要调用dict而不是使用大括号,你可以使用键/值元组的序列构造器:

d = dict([(True, "True"), (False, "False")])

我想说你展示的代码片段有点傻。Python中的bool类型是int的一个子类,所以如果你想的话,可以对TrueFalse进行数学运算。字典索引的代码实际上等同于1-True,结果是0

撰写回答