Python СинтаксисError с dict (1 =...), но {1:...} работает

Python, похоже, имеет несогласованность в том, какие ключи он примет для dicts. Или, по-другому, он позволяет определенным типам ключей одним способом определения dicts, но не в других:

>>> d = {1:"one",2:2}
>>> d[1]
'one'
>>> e = dict(1="one",2=2)
  File "<stdin>", line 1
  SyntaxError: keyword can't be an expression

Является ли обозначение {...} более фундаментальным, а dict(...) просто синтаксическим сахаром? Это потому, что для Python просто нет возможности parse dict(1="one")?

Мне любопытно...

Ответ 1

Это не проблема dict, но артефакт синтаксиса Python: аргументы ключевого слова должны быть действительными идентификаторами, а 1 и 2 - нет.

Если вы хотите использовать что-либо, не являющееся строкой, следуя правилам идентификатора Python в качестве ключа, используйте синтаксис {}. Синтаксис аргумента ключевого слова конструктора существует только для удобства в некоторых особых случаях.

Ответ 2

dict - это вызов функции, а ключевые слова функции должны быть идентификаторами.

Ответ 3

Если вы прочитали документацию , вы узнаете, что нота dict = {stringA = 1, stringB = 2} действительна, когда ключи являются простыми строками:

Когда ключи являются простыми строками, иногда легче указать пары с использованием аргументов ключевого слова:

>>>
>>> dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'jack': 4098, 'guido': 4127}

Так как целые числа (или другие числа) не являются допустимыми аргументами ключевого слова, dict = {1 = 2, 3 = 4} будет терпеть неудачу, поскольку любой вызов функции будет, если вы передали ему аргумент, назвав его числом:

>>> def test(**kwargs):
...     for arg in kwargs:
...         print arg, kwargs[arg]
... 
>>> test(a=2,b=3)
a 2
b 3
>>> test(1=2, 3=4)
  File "<stdin>", line 1
SyntaxError: keyword can't be an expression

Ответ 4

Как сказал другой ответ, dict является вызовом функции. Он имеет три синтаксических формы.

Форма:

dict(**kwargs) -> new dictionary initialized with the name=value pairs
   in the keyword argument list.  For example:  dict(one=1, two=2)

Ключи (или name, используемые в этом случае) должны быть действительны Python identifiers, а int недействительны.

Ограничение - это не только функция dict. Вы можете продемонстрировать ее так:

>>> def f(**kw): pass
... 
>>> f(one=1)    # this is OK
>>> f(1=one)    # this is not
  File "<stdin>", line 1
SyntaxError: keyword can't be an expression

Однако есть две другие синтаксические формы, которые вы можете использовать.

Существует:

dict(iterable) -> new dictionary initialized as if via:
       d = {}
       for k, v in iterable:
           d[k] = v

Пример:

>>> dict([(1,'one'),(2,2)])
{1: 'one', 2: 2}

И из отображения:

dict(mapping) -> new dictionary initialized from a mapping object's
   (key, value) pairs

Пример:

>>> dict({1:'one',2:2})
{1: 'one', 2: 2}

В то время как это может показаться не очень большим (диктофон из литерала dict), помните, что Counter и defaultdict являются сопоставлениями, и вы можете скрывать один из них в dict:

>>> from collections import Counter
>>> Counter('aaaaabbbcdeffff')
Counter({'a': 5, 'f': 4, 'b': 3, 'c': 1, 'e': 1, 'd': 1})
>>> dict(Counter('aaaaabbbcdeffff'))
{'a': 5, 'c': 1, 'b': 3, 'e': 1, 'd': 1, 'f': 4}