it-swarm.com.de

Tiefe Kopie eines Diktats in python

Ich möchte eine tiefe Kopie eines dict in Python machen. Leider existiert die Methode .deepcopy() für dict nicht. Wie mache ich das?

>>> 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

Die letzte Zeile sollte 3 Sein.

Ich möchte, dass Änderungen in my_dict Keinen Einfluss auf den Schnappschuss my_copy Haben.

Wie mache ich das? Die Lösung sollte mit Python 3.x kompatibel sein.

277

Wie wäre es mit:

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

Python 2 oder 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
>>>

dict.copy () ist eine flache Kopierfunktion für das Wörterbuch
id ist eine integrierte Funktion, die Ihnen die Adresse der Variablen gibt

Zuerst müssen Sie verstehen, warum dieses spezielle Problem auftritt.

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

Die Adresse der Liste, die in beiden Dikten für den Schlüssel 'a' enthalten ist, zeigt auf dieselbe Position.
Wenn Sie also den Wert der Liste in my_dict ändern, ändert sich auch die Liste in my_copy.


Lösung:

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

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

Oder Sie können DeepCopy wie oben erwähnt verwenden.

28
theBuzzyCoder

Python 3.x

von Kopie importieren Deepcopy

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

Ohne DeepCopy kann ich das Hostnamen-Wörterbuch nicht aus meinem Domain-Wörterbuch entfernen.

Ohne Deepcopy erhalte ich folgende Fehlermeldung:

"RuntimeError: dictionary changed size during iteration"

... wenn ich versuche, das gewünschte Element aus meinem Wörterbuch in einem anderen Wörterbuch zu entfernen.

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

domain ist ein Dictionary-Objekt

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

Beispielausgabe: [orginal] domains = {'localdomain': {'localhost': {'all': '4000'}}}

[new] domains = {'localdomain': {}}}

Was hier vor sich geht, ist, dass ich über eine Kopie eines Wörterbuchs iteriere, anstatt über das Wörterbuch selbst zu iterieren. Mit dieser Methode können Sie Elemente nach Bedarf entfernen.

12
xpros