Quelle est la syntaxe préférée pour initialiser un dict: les accolades {} ou la fonction dict ()?

212

Je fais des efforts pour apprendre Python et je porte une attention particulière aux normes de codage courantes. Cela peut sembler être une question inutile, mais j'essaie de me concentrer sur les meilleures pratiques au fur et à mesure que j'apprends, donc je n'ai pas à désapprendre de «mauvaises» habitudes.

Je vois deux méthodes courantes pour initialiser un dict:

a = {
    'a': 'value',
    'another': 'value',
}

b = dict( 
    a='value',
    another='value',
)

Lequel est considéré comme "plus pythonique"? Lequel utilisez-vous? Pourquoi?

daotoad
la source
5
Quel tutoriel utilisez-vous? Où avez-vous vu des exemples de confusion?
S.Lott
2
Eh bien, j'ai utilisé le didacticiel Python, Plongez dans Python, puis une variété de blogs, de publications SO et d'autres ressources googlées. Les documents officiels utilisent {}assez uniformément, mais je vois beaucoup de l' dict()approche explicite ailleurs. Je pouvais voir l'avantage d'une syntaxe explicite, mais l'absence de l'approche dans les documents officiels m'a rendu suspect. Après avoir posté cela, j'ai regardé les documents de la bibliothèque dictet j'ai trouvé la prudence que les clés doivent être des identifiants valides lorsqu'un explicite dictest utilisé pour initialiser un dict.
daotoad
2
Comment "dict ()" est-il plus explicite que "{}"? Je ne comprends pas votre confusion. Les deux me paraissent explicites. Pouvez-vous fournir une citation ou une référence qui vous fait dire que "dict" est "explicite" et "{}" n'est pas explicite? D'où pensez-vous que cette distinction est née?
S.Lott
21
La distinction est l'orthographe. dict()est orthographié dictutilisations --Il le nom du type. Les accolades ( {}) s'appuient sur la ponctuation pour identifier le type.
daotoad

Réponses:

235

Accolades. Passer des arguments de mots clés dans dict(), même si cela fonctionne à merveille dans de nombreux scénarios, ne peut initialiser une carte que si les clés sont des identifiants Python valides.

Cela marche:

a = {'import': 'trade', 1: 7.8}
a = dict({'import': 'trade', 1: 7.8})

Cela ne fonctionnera pas:

a =                  dict(import='trade', 1=7.8)
>> SyntaxError: invalid syntax  ^
Wai Yip Tung
la source
85

Les premières accolades bouclées. Sinon, vous rencontrez des problèmes de cohérence avec des clés contenant des caractères impairs, comme =.

# Works fine.
a = {
    'a': 'value',
    'b=c': 'value',
}

# Eeep! Breaks if trying to be consistent.
b = dict( 
    a='value',
    b=c='value',
)
ambre
la source
11
C'est exactement pourquoi on peut préférer la méthode dict () pour l'initialisation, elle force les clés de dictionnaire à être des identifiants valides, donc elles sont compatibles avec, par exemple, ** kwargs, et les clés sont des noms d'attribut valides.
RufusVS
57

La première version est préférable:

  • Cela fonctionne pour toutes sortes de clés, vous pouvez par exemple dire {1: 'one', 2: 'two'}. La deuxième variante ne fonctionne que pour (certaines) clés de chaîne. L'utilisation de différents types de syntaxe en fonction du type de clés serait une incohérence inutile.
  • C'est plus rapide:

    $ python -m timeit "dict(a='value', another='value')"
    1000000 loops, best of 3: 0.79 usec per loop
    $ python -m timeit "{'a': 'value','another': 'value'}"
    1000000 loops, best of 3: 0.305 usec per loop
  • Si la syntaxe spéciale pour les littéraux de dictionnaire n'était pas destinée à être utilisée, elle n'existerait probablement pas.
stephan
la source
3

Je pense que la première option est meilleure parce que vous allez accéder aux valeurs en tant que ['a'] ou ['autre']. Les clés de votre dictionnaire sont des chaînes et il n'y a aucune raison de prétendre qu'elles ne le sont pas. Pour moi, la syntaxe des mots clés semble intelligente au premier abord, mais obscure au second regard. Cela n'a de sens pour moi que si vous travaillez avec __dict__, et les mots clés vont devenir des attributs plus tard, quelque chose comme ça.

diviser par zéro
la source
3

Pour info, au cas où vous auriez besoin d'ajouter des attributs à votre dictionnaire (des choses qui sont attachées au dictionnaire, mais qui ne sont pas une des clés), alors vous aurez besoin du deuxième formulaire. Dans ce cas, vous pouvez initialiser votre dictionnaire avec des clés ayant des caractères arbitraires, une à la fois, comme ceci:

    class mydict(dict): pass
    a = mydict()        
    a["b=c"] = 'value'
    a.test = False
Joshua Richardson
la source
2

C'est parfois dict()un bon choix:

a=dict(zip(['Mon','Tue','Wed','Thu','Fri'], [x for x in range(1, 6)]))

mydict=dict(zip(['mon','tue','wed','thu','fri','sat','sun'],

[random.randint (0,100) pour x dans la plage (0,7)]))

Deqing
la source
2
Il existe une fonction énumération qui pourrait mieux faire cela. D'ailleurs, il existe un type Enum qui peut mieux faire ce que vous faites ici. De plus, ce n'est pas vraiment une réponse à la question.
dusktreader
2

J'utilise presque toujours des accolades; cependant, dans certains cas où j'écris des tests, je fais l'empaquetage / déballage des mots clés, et dans ces cas, dict () est beaucoup plus facile à gérer, car je n'ai pas besoin de changer:

a=1,
b=2,

à:

'a': 1,
'b': 2,

Cela aide également dans certaines circonstances où je pense que je pourrais vouloir le transformer en un tuple nommé ou une instance de classe ultérieurement.

Dans l'implémentation elle-même, en raison de mon obsession pour l'optimisation, et quand je ne vois pas un avantage de maintenance particulièrement énorme, je privilégierai toujours les accolades.

Dans les tests et l'implémentation, je n'utiliserais jamais dict () s'il y a une chance que les clés ajoutées alors, ou à l'avenir, soit:

  • Pas toujours une chaîne
  • Contient non seulement des chiffres, des lettres ASCII et des traits de soulignement
  • Commencez par un entier ( dict(1foo=2)déclenche une SyntaxError)
user989266
la source