web-dev-qa-db-fra.com

Méthode rapide pour copier le dictionnaire en Python

J'ai un programme Python qui fonctionne beaucoup avec les dictionnaires. Je dois faire des copies de dictionnaires des milliers de fois. J'ai besoin d'une copie des clés et du contenu associé. La copie sera modifiée. et ne doit pas être lié à l'original (par exemple, les modifications apportées à la copie ne doivent pas affecter l'original.)

Les clés sont des chaînes, les valeurs sont des entiers (0/1).

J'utilise actuellement un moyen simple:

newDict = oldDict.copy()

Le profilage de mon code montre que l'opération de copie prend la plupart du temps.

Existe-t-il des alternatives plus rapides à la méthode dict.copy()? Quel serait le plus rapide?

88
Joern

En regardant source C pour les opérations Python dict, vous pouvez constater qu’elles font une copie assez naïve (mais efficace). jusqu'à un appel à PyDict_Merge:

PyDict_Merge(PyObject *a, PyObject *b, int override)

Cela permet de vérifier rapidement si le même objet et le même objet contiennent des objets. Après cela, il effectue un généreux redimensionnement/affectation ponctuel au dict cible, puis copie les éléments un par un. Je ne vois pas que vous deveniez beaucoup plus rapide que la copy() intégrée.

62
Daniel DiPaolo

Apparemment, dict.copy est plus rapide, comme vous dites.

[utdmr@utdmr-Arch ~]$ python -m timeit -s "d={1:1, 2:2, 3:3}" "new = d.copy()"
1000000 loops, best of 3: 0.238 usec per loop
[utdmr@utdmr-Arch ~]$ python -m timeit -s "d={1:1, 2:2, 3:3}" "new = dict(d)"
1000000 loops, best of 3: 0.621 usec per loop
[utdmr@utdmr-Arch ~]$ python -m timeit -s "from copy import copy; d={1:1, 2:2, 3:3}" "new = copy(d)"
1000000 loops, best of 3: 1.58 usec per loop
54
utdemir

Pouvez-vous fournir un exemple de code afin que je puisse voir comment vous utilisez copy () et dans quel contexte?

Vous pourriez utiliser

new = dict(old)

Mais je ne pense pas que ce sera plus rapide.

12
MikeVaughan

En fonction des éléments laissés à la spéculation, vous voudrez peut-être envelopper le dictionnaire d'origine et effectuer une copie en quelque sorte.

La "copie" est alors un dictionnaire qui recherche des éléments dans le dictionnaire "parent", s'il ne contient pas déjà la clé --- mais insère des modifications en soi.

Cela suppose que vous ne modifiez pas l'original et que les recherches supplémentaires ne coûtent pas plus cher.

3
Alex Brasetvik

Je me rends compte que c’est un vieux fil de discussion, mais c’est un bon résultat dans les moteurs de recherche pour "dict copy python", et le meilleur résultat pour "dict copy performance", et j'estime que c'est pertinent.

À partir de Python 3.7, newDict = oldDict.copy() est jusqu’à 5.5 fois plus rapide qu’auparavant. Il est à noter que pour le moment, newDict = dict(oldDict) ne semble pas avoir cette performance. augmenter.

Il y a un peu plus d'informations ici .

3
iandioch

Les mesures dépendent de la taille du dictionnaire. Pour 10000 entrées, copie (d) et d.copy () sont presque identiques.

a = {b: b for b in range(10000)} 
In [5]: %timeit copy(a)
10000 loops, best of 3: 186 µs per loop
In [6]: %timeit deepcopy(a)
100 loops, best of 3: 14.1 ms per loop
In [7]: %timeit a.copy()
1000 loops, best of 3: 180 µs per loop
2