618 votes

Copie profonde d'un dict en python

Je voudrais faire une copie profonde d'une dict en python. Malheureusement, le .deepcopy() n'existe pas pour la méthode dict . Comment je fais ça ?

>>> my_dict = {'a': [1, 2, 3], 'b': [4, 5, 6]}
>>> my_copy = my_dict.deepcopy()
Traceback (most recent calll last):
  File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'deepcopy'
>>> my_copy = my_dict.copy()
>>> my_dict['a'][2] = 7
>>> my_copy['a'][2]
7

La dernière ligne devrait être 3 .

Je voudrais que les modifications dans my_dict n'ont pas d'impact sur l'instantané my_copy .

Comment je fais ça ? La solution doit être compatible avec Python 3.x.

3 votes

Je ne sais pas si c'est un doublon, mais ceci : stackoverflow.com/questions/838642/python-dictionnaire-deepcopy est terriblement proche.

-2voto

stackuser83 Points 160

Je suis en train d'apprendre Python (3.7.7 en tant qu'évaluateur d'expression faisant partie d'un environnement logiciel d'interface REPL) aujourd'hui, et j'ai constaté qu'il y a une frozenset qui pourraient être utiles à cette fin. Je l'ai appris à cette réponse : https://stackoverflow.com/a/11251781/832705

une certaine documentation devrait être ici : https://docs.python.org/3/library/stdtypes.html?highlight=frozenset#frozenset

Je pense que le frozenset devrait être comme une copie assez profonde, à des fins d'itération, d'un objet de type liste/dictionnaire qui a tendance à lancer des erreurs "RuntimeError : dictionary changed size during iteration" pendant l'itération.

J'ai l'intention de revenir à l'apprentissage de frozenset plus tard. Si vous votez contre cette réponse, parce qu'elle est fausse, non applicable ou pour une autre raison, cela me rappellera au moins de me renseigner davantage.

-10voto

Eric Hoffman Points 1

Une solution plus simple (à mon avis) consiste à créer un nouveau dictionnaire et à le mettre à jour avec le contenu de l'ancien :

my_dict={'a':1}

my_copy = {}

my_copy.update( my_dict )

my_dict['a']=2

my_dict['a']
Out[34]: 2

my_copy['a']
Out[35]: 1

Le problème de cette approche est qu'elle n'est pas forcément "assez profonde", c'est-à-dire qu'elle n'est pas récursivement profonde. Elle est suffisante pour les objets simples mais pas pour les dictionnaires imbriqués. Voici un exemple où elle n'est peut-être pas assez profonde :

my_dict1={'b':2}

my_dict2={'c':3}

my_dict3={ 'b': my_dict1, 'c':my_dict2 }

my_copy = {}

my_copy.update( my_dict3 )

my_dict1['b']='z'

my_copy
Out[42]: {'b': {'b': 'z'}, 'c': {'c': 3}}

En utilisant Deepcopy(), je peux éliminer le comportement semi-profond, mais je pense qu'il faut décider de l'approche la plus adaptée à votre application. Dans la plupart des cas, vous pouvez ne pas vous en soucier, mais vous devez être conscient des pièges possibles... dernier exemple :

import copy

my_copy2 = copy.deepcopy( my_dict3 )

my_dict1['b']='99'

my_copy2
Out[46]: {'b': {'b': 'z'}, 'c': {'c': 3}}

14 votes

Cela fait une copie superficielle du dict, ce qui n'est pas ce que l'auteur de la question demandait. Les objets qu'il contient ne sont pas copiés eux-mêmes. Une façon plus simple de faire une copie superficielle est la suivante my_dict.copy() !

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