2012-04-30 5 views
10

Python wydaje się mieć niespójność w tym, jakie klucze zaakceptuje dla dyktowania. Lub, innymi słowy, pozwala na pewne rodzaje kluczy w jeden sposób definiowania dicts, ale w innych nie:python SyntaxError z dict (1 = ...), ale {1: ...} działa

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

Czy notacja {...} bardziej fundamentalne i dict(...) tylko cukier syntaktyczny? Czy to dlatego, że Python nie ma po prostu sposobu na parse dict(1="one")?

jestem ciekaw ...

Odpowiedz

17

To nie jest dict problem, ale artefaktem składni Pythona: argumenty słów kluczowych musi być ważne identyfikatory i 1 i 2 nie są.

Jeśli chcesz używać elementów, które nie są ciągami po zasadach identyfikatora Python jako klucz, użyj składni {}. Składnia argumentów konstruktora słów kluczowych jest dostępna dla wygody w niektórych szczególnych przypadkach.

9

dict to wywołanie funkcji, a słowa kluczowe funkcji muszą być identyfikatorami.

1

Jeśli czytasz documentation, dowiesz się, że notacja dict = {stringA = 1, stringB = 2} jest ważna, gdy klawisze są proste ciągi:

Gdy klawisze są proste ciągi znaków, czasem jest łatwiej określić pary używając argumentów słów kluczowych :

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

Ponieważ całkowite (lub inne numery) nie są ważne argumenty słowa kluczowego, dict = {1 = 2, 3 = 4} zawiedzie w każdym wywołaniu funkcji będzie, jeśli ciebie argument przekazany do niego podczas nazywania go z numerem:

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

Jak inni odpowiedź, dict jest wywołanie funkcji. Ma trzy formy syntaktyczne.

postać:

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

Klucze (lub name, użyte w tym przykładzie) musi być ważne Pythona identifiers i typu int nie są prawidłowe.

Ograniczenie to nie tylko funkcja dict Można wykazać go tak:

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

Jednakże istnieją dwie inne formy składniowe można użyć.

Istnieje:

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

przykład:

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

A z mapowania:

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

przykład:

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

Mimo, że nie może wydawać się dużo (dict od dict dosłownym) należy pamiętać, że Counter i defaultdict są mapowania i to w jaki sposób przekształcać jedną z tych, do 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}