2012-04-30 20 views
10

Python parece tener una incoherencia en el tipo de claves que aceptará para los dicts. O, dicho de otra manera, permite que ciertos tipos de llaves de una manera de definir predice, pero no en otros:python SyntaxError con dict (1 = ...), pero {1: ...} funciona

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

es la notación {...} más fundamental, y dict(...) azúcar sintáctica solo? ¿Es porque simplemente no hay forma de que Python sea parse dict(1="one")?

tengo curiosidad ...

Respuesta

17

Esto no es una cuestión dict, sino un artefacto de la sintaxis de Python: argumentos de palabra clave deben ser identificadores válidos, y 1 y 2 no lo son.

Cuando desee utilizar cualquier cosa que no sea una cadena siguiendo las reglas de identificación de Python como una clave, use la sintaxis {}. La sintaxis del argumento de la palabra clave constructor está ahí por conveniencia en algunos casos especiales.

9

dict es una llamada a función, y las palabras clave de función deben ser identificadores.

1

Si usted lee la documentation, usted aprenderá que la notación dict = {stringA = 1, stringB = 2} es válida cuando las claves son cadenas simples:

Cuando las claves son cadenas simples, a veces es más fácil especificar pares utilizando argumentos de palabra clave :

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

Desde enteros (u otros números) no son válidos los argumentos de palabras clave, la dict = {1 = 2, 3 = 4} fallará como cualquier llamada a una función haría si un argumento pasado a ella mientras nombrarlo con un número:

>>> 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 
1

Como otra respuesta han declarado, dict es una llamada a la función. Tiene tres formas sintácticas.

la forma:

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

Las teclas (o name tal como se utiliza en este caso) debe ser válido Python identifiers, y ints no son válidas.

La limitación es no sólo la función dict Usted puede demostrar que de este modo:

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

Sin embargo, existen otras dos formas sintácticas de que puede utilizar.

No:

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

Ejemplo:

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

Y a partir de una cartografía:

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

Ejemplo:

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

Mientras que puede no parecer mucho (un diccionario de un diccionario literal) tener en cuenta que Counter y defaultdict son asignaciones y esto es lo que le encubierta uno de los que un diccionario:

>>> 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} 
Cuestiones relacionadas