70 votes

Quelle est la différence entre dict () et {}?

Donc, disons que j'ai envie de faire un dictionnaire. Nous l'appellerons d. Mais il y a de multiples façons d'initialiser un dictionnaire en Python! Par exemple, je pourrais faire ceci:

d = {'hash': 'bang', 'slash': 'dot'}

Ou je pourrais faire ceci:

d = dict(hash='bang', slash='dot')

Ou cela, curieusement:

d = dict({'hash': 'bang', 'slash': 'dot'})

Ou ceci:

d = dict([['hash', 'bang'], ['slash', 'dot']])

Et une autre multitude de façons avec l' dict() fonction. Alors, évidemment, l'une des choses dict() fournit la flexibilité en matière de syntaxe et de l'initialisation. Mais ce n'est pas ce que je demande.

Dire que j'ai été faire d seulement un dictionnaire vide. Ce qui se passe derrière les coulisses de l'interpréteur Python quand je le fais, d = {} contre d = dict()? Est-ce simplement deux façons de faire la même chose? N'utilisez {} ont l' complémentaires appel d' dict()? A-t-on (même infime) de plus de ressources que les autres? Alors que la question est vraiment complètement sans importance, c'est une curiosité, j'aimerais avoir des réponses.

78voto

Steven Huwig Points 8029
 >>> def f():
...     return {'a' : 1, 'b' : 2}
... 
>>> def g():
...     return dict(a=1, b=2)
... 
>>> g()
{'a': 1, 'b': 2}
>>> f()
{'a': 1, 'b': 2}
>>> import dis
>>> dis.dis(f)
  2           0 BUILD_MAP                0
              3 DUP_TOP             
              4 LOAD_CONST               1 ('a')
              7 LOAD_CONST               2 (1)
             10 ROT_THREE           
             11 STORE_SUBSCR        
             12 DUP_TOP             
             13 LOAD_CONST               3 ('b')
             16 LOAD_CONST               4 (2)
             19 ROT_THREE           
             20 STORE_SUBSCR        
             21 RETURN_VALUE        
>>> dis.dis(g)
  2           0 LOAD_GLOBAL              0 (dict)
              3 LOAD_CONST               1 ('a')
              6 LOAD_CONST               2 (1)
              9 LOAD_CONST               3 ('b')
             12 LOAD_CONST               4 (2)
             15 CALL_FUNCTION          512
             18 RETURN_VALUE
 

dict () est apparemment un C intégré. Une personne très intelligente ou dévouée (pas moi) pourrait consulter la source de l’interprète et vous en dire plus. Je voulais juste montrer dis.dis. :)

41voto

DNS Points 17577

En ce qui concerne la performance:

 >>> from timeit import timeit
>>> timeit("a = {'a': 1, 'b': 2}")
0.424...
>>> timeit("a = dict(a = 1, b = 2)")
0.889...
 

28voto

Matt Good Points 1313

@Jacob: Il y a une différence dans la façon dont les objets sont alloués, mais ils ne sont pas de copie sur écriture. Python alloue une taille fixe "liste libre" où il peut rapidement allouer dictionnaire d'objets (jusqu'à ce qu'il se remplit). Dictionnaires alloués par l' {} de la syntaxe (ou un C appel d' PyDict_New) peuvent venir à partir de cette liste libre. Lorsque le dictionnaire n'est plus référencé, il revient à la liste libre et que le bloc de mémoire peuvent être réutilisés (si les champs sont remis à zéro en premier).

Ce premier dictionnaire est immédiatement retourné à la libre liste, et la prochaine sera de réutilisation de la mémoire de l'espace:

>>> id({})
340160
>>> id({1: 2})
340160

Si vous gardez une référence, la prochaine dictionnaire viendra le prochain emplacement libre:

>>> x = {}
>>> id(x)
340160
>>> id({})
340016

Mais nous pouvons supprimer la référence à ce dictionnaire libre et sa fente:

>>> del x
>>> id({})
340160

Depuis l' {} syntaxe est gérée en byte-code, il peut utiliser cette optimisation mentionnés ci-dessus. D'autre part dict() est traité comme un constructeur de classe et Python utilise le générique de l'allocateur de mémoire, ce qui ne permet pas de suivre facilement un schéma prévisible comme la gratuit de la liste ci-dessus.

Aussi, à la recherche lors de la compilation.c à partir de la version 2.6 de Python, avec l' {} de la syntaxe, il semble à la pré-taille de la table de hachage basée sur le nombre d'éléments, c'est le stockage qui est connu au moment de l'analyse.

9voto

Benjamin Peterson Points 5277

Fondamentalement, {} est une syntaxe et est géré au niveau de la langue et du bytecode. dict () est juste un autre construit avec une syntaxe d'initialisation plus flexible. Notez que dict () n’a été ajouté qu’au milieu de la série 2.x.

7voto

Jacob Gabrielson Points 8800

Mise à jour: merci pour les réponses. Retiré de la spéculation à propos de copy-on-write.

Une autre différence entre {} et dict que dict toujours alloue un nouveau dictionnaire (même si le contenu est statique) alors qu' {} n'est pas toujours le faire (voir mgood réponse pour quand et pourquoi):

def dict1():
    return {'a':'b'}

def dict2():
    return dict(a='b')

print id(dict1()), id(dict1())
print id(dict2()), id(dict2())

produit:

$ ./mumble.py
11642752 11642752
11867168 11867456

Je ne suggère pas que vous essayez de profiter de cela ou pas, cela dépend de la situation, il suffit de pointer la. (Il est aussi probablement évident, à partir du démontage , si vous comprenez les opcodes).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X