Использование True / False в качестве ключей-как/почему это работает?
Мне удобно использовать этот простой синтаксис для инициализации a dictionary
d = {'a':'Apple','b':'Bat'};
Сегодня, читая страницу, Я столкнулся с этим странным фрагментом кода
{True:0, False:1}[True];
Мне было интересно, почему/как это может работать? True
и False
- зарезервированные ключевые слова.,
и так, этот безумный синтаксис должен быть бессмысленным (для компилятора), но он есть
нет.
>>> 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 ответа:
Хотя они и являются ключевыми словами (в Python 3),
Таким образом, вы можете использовать их везде, где значение имеет смысл. Поскольку они хешируются, это включает в себя использование их в качестве ключей словаря. Вы можете сделать:True
иFalse
по-прежнему являются именами объектов (они, соответственноbool(1)
иbool(0)
).d = {} d[True] = "True" d[False] = "False"
Вы можете получить тот же словарь непосредственно с фигурными скобками (
d = {True: "True", False: "False"}
), но не используя конструкторdict
с аргументами ключевых слов. Ключевая версия конструктора строит только дикты с ключами, которые являются строками, и эти строки должны быть легальными идентификаторами Python.True
иFalse
не являются строками и (поскольку они являются ключевыми словами) не могут использоваться в качестве идентификаторов.Вы, конечно, можете использовать конструктор последовательности кортежей ключей/значений, если есть какая-то причина, по которой вам нужно вызывать
dict
, а не использовать скобки:Я бы отметил, что фрагмент кода, который вы показываете, немного глуповат. Типd = dict([(True, "True"), (False, "False")])
bool
в Python является подклассомint
, поэтому вы можете выполнять математические операции надTrue
илиFalse
, Если хотите. Код индексации словаря эквивалентен1-True
, который будет0
.
Почему это должно быть бессмысленно?
True
иFalse
- это значения, а не ключевые слова. Вот почему вы можете сравнить с ними другие ценности.Вы также не можете использовать целые числа в конструкторе dict. Это ограничение аргументов ключевых слов, а не словарей.
True
иFalse
- это не ключевые слова , а реальные объекты. Вы можете проверить это в интерпретаторе Python (здесь используется 2.7, но то же самое относится и к 3.x):Таким образом, они могут использоваться в качестве ключей в dict или подобной структуре.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, Вы могли использовать
True
иFalse
в качестве имен параметров дляdict()
:>>> d = dict(True="true", False="false") >>> d {'False': 'false', 'True': 'true'}
Однако, чтобы избежать путаницы, интерпретатор Python 3 запрещает вам это делать, так как теперь он по существу обрабатывает их как ключевые слова -- но на самом деле они все еще объекты. (Я думаю, можно сказать, что они оба, в некотором роде.)