web-dev-qa-db-fra.com

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

Je fais des efforts pour apprendre le python et je suis très attentif aux normes de codage courantes. Cela peut sembler une question de choix délicat, mais j'essaie de me concentrer sur les meilleures pratiques à mesure que j'apprends, de sorte que je n'ai pas à désapprendre les "mauvaises" habitudes.

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

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

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

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

196
daotoad

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

En d'autres termes, il ne peut pas faire:

a = {'import': 'trade', 1: 7.8}
221
Wai Yip Tung

Le premier, les accolades. 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',
)
78
Amber

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

  • Cela fonctionne pour toutes sortes de clés, vous pouvez donc, 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é constituerait 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.
56
stephan

Je pense que la première option est préférable car vous allez accéder aux valeurs sous forme de ['a'] ou de ['other']. 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 astucieuse au début, mais obscure au second abord. Cela n’a de sens que si vous travaillez avec __dict__, et les mots-clés deviendront des attributs plus tard, quelque chose comme ça.

3
dividebyzero

Pour votre information, au cas où vous auriez besoin d'ajouter des attributs à votre dictionnaire (des éléments qui sont attachés au dictionnaire, mais qui ne sont pas l'une des clés), vous aurez alors besoin du second formulaire. Dans ce cas, vous pouvez initialiser votre dictionnaire avec des clés à caractères arbitraires, une par une, comme suit:

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

J'utilise presque toujours des accolades; Cependant, dans certains cas où j'écris des tests, je fais le mot-clé empaquetage/décompression, 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 instance de nom ou en classe nommée plus tard.

Dans l'implémentation même, en raison de mon obsession pour l'optimisation et lorsque 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 à ce moment-là, ou à l'avenir, soient:

  • Pas toujours être une chaîne
  • Non seulement contenir des chiffres, ASCII lettres et des traits de soulignement
  • Commencez par un entier (dict(1foo=2) soulève une SyntaxError)
2
user989266

Parfois, dict() est 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)]))

1
Deqing