web-dev-qa-db-fra.com

Copie complète d'un dict dans python

Je voudrais faire une copie complète d'un dict en python. Malheureusement, la méthode .deepcopy() n'existe pas pour le 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 doit être 3.

Je voudrais que les modifications dans my_dict n'affectent pas l'instantané my_copy.

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

277
Olivier Grégoire

Que diriez-vous:

import copy
d = { ... }
d2 = copy.deepcopy(d)

Python 2 ou 3:

Python 3.2 (r32:88445, Feb 20 2011, 21:30:00) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import copy
>>> my_dict = {'a': [1, 2, 3], 'b': [4, 5, 6]}
>>> my_copy = copy.deepcopy(my_dict)
>>> my_dict['a'][2] = 7
>>> my_copy['a'][2]
3
>>>
398

dict.copy () est une fonction de copie superficielle pour dictionnaire
( id est une fonction intégrée qui vous donne l'adresse de la variable

Vous devez d’abord comprendre "pourquoi ce problème particulier se produit-il?"

In [1]: my_dict = {'a': [1, 2, 3], 'b': [4, 5, 6]}

In [2]: my_copy = my_dict.copy()

In [3]: id(my_dict)
Out[3]: 140190444167808

In [4]: id(my_copy)
Out[4]: 140190444170328

In [5]: id(my_copy['a'])
Out[5]: 140190444024104

In [6]: id(my_dict['a'])
Out[6]: 140190444024104

L'adresse de la liste présente dans les deux dessins pour la clé "a" pointe vers le même emplacement.
Par conséquent, lorsque vous modifiez la valeur de la liste dans my_dict, la liste dans my_copy change également.


Solution:

In [7]: my_copy = {key: value[:] for key, value in my_dict.items()}

In [8]: id(my_copy['a'])
Out[8]: 140190444024176

Ou vous pouvez utiliser deepcopy comme mentionné ci-dessus.

28
theBuzzyCoder

Python 3.x

à partir de copie en copie profonde

my_dict = {'one': 1, 'two': 2}
new_dict_deepcopy = deepcopy(my_dict)

Sans copie profonde, je ne peux pas supprimer le dictionnaire de noms d'hôtes de mon dictionnaire de domaine.

Sans copie profonde, j'obtiens l'erreur suivante:

"RuntimeError: dictionary changed size during iteration"

... lorsque j'essaie de supprimer l'élément souhaité de mon dictionnaire à l'intérieur d'un autre dictionnaire.

import socket
import xml.etree.ElementTree as ET
from copy import deepcopy

domaine est un objet dictionnaire

def remove_hostname(domain, hostname):
    domain_copy = deepcopy(domain)
    for domains, hosts in domain_copy.items():
        for Host, port in hosts.items():
           if Host == hostname:
                del domain[domains][Host]
    return domain

Exemple de résultat: [orginal] domains = {'localdomain': {'localhost': {'all': '4000'}}}

[nouveau] domaines = {'localdomain': {}}}

Donc, ce qui se passe ici, c'est que je parcoure une copie d'un dictionnaire plutôt que de le parcourir lui-même. Avec cette méthode, vous pouvez supprimer des éléments si nécessaire.

12
xpros