HOWTO · Python

Wie man ein Dictionary in Python kopiert

Die Beschreibung erklärt, wann eine Zuweisung einen weiteren Namen für dasselbe Dictionary anlegt, wann eine flache Kopie genügt und wann eine tiefe Kopie verschachtelte Werte unabhängig macht.

Auf dieser Seite

Verwende dict(source) oder source.copy(), um ein neues äußeres Dictionary anzulegen. Beide erstellen flache Kopien: Verschachtelte Werte bleiben gemeinsam genutzt. Verwende copy.deepcopy(source), wenn auch verschachtelte veränderliche Werte unabhängig sein müssen. Eine Zuweisung mit = erstellt keine Kopie. Weitere Informationen findest du im Python-Dictionary-Tutorial und in der Dokumentation zum copy-Modul.

Eine Dictionary-Zuweisung erzeugt einen Alias

Eine Zuweisung bindet einen weiteren Namen an dasselbe Dictionary-Objekt. Änderungen am Dictionary über einen der beiden Namen sind über beide sichtbar. Einen Namen neu zuzuweisen ist etwas anderes: Danach verweist dieser Name auf ein anderes Objekt, ohne das ursprüngliche Objekt oder den anderen Namen zu verändern.

Dieses vollständige Beispiel ändert das gemeinsam genutzte Dictionary über meal und weist meal anschließend ein neues Dictionary zu:

food = {"Fruit": "Orange", "Vegetable": "Lettuce"}
meal = food
meal["Fruit"] = "Banana"
print(food)
print(meal)
meal = {"Fruit": "Apple"}
print(food)
print(meal)
{'Fruit': 'Banana', 'Vegetable': 'Lettuce'}
{'Fruit': 'Banana', 'Vegetable': 'Lettuce'}
{'Fruit': 'Banana', 'Vegetable': 'Lettuce'}
{'Fruit': 'Apple'}

Die ersten beiden ausgegebenen Werte stimmen überein, weil beide Namen zu diesem Zeitpunkt auf dasselbe Objekt verweisen. Nach der Zuweisung an meal verweist nur dieser Name auf das neu erstellte Dictionary; food verweist weiterhin auf das ursprüngliche. Dieser Unterschied erklärt, warum eine Wertänderung über einen Namen auch über den anderen sichtbar ist, während eine Neuzuweisung einer Variablen das Objekt, auf das der andere Name verweist, nicht ersetzt.

Python-Dictionary-Variablen, die auf dasselbe Dictionary verweisen

Ein Dictionary flach kopieren

Der eingebaute Konstruktor dict() und die Methode copy() eines Dictionarys erstellen jeweils ein neues äußeres Dictionary. Wird in dieser Kopie ein Eintrag auf oberster Ebene geändert oder entfernt, bleibt das Original davon unberührt. Beide Dictionarys verweisen jedoch weiterhin auf dieselben verschachtelten Listen, Dictionarys oder anderen veränderlichen Werte. Änderungen an diesen Werten können deshalb über beide Namen sichtbar sein.

Hier erhalten by_constructor und by_method jeweils ein eigenes äußeres Dictionary. Die verschachtelte Liste wird gemeinsam genutzt; ein neuer Wert für den Schlüssel name betrifft dagegen nur die ausgewählte Kopie:

source = {"name": "Sherlock", "numbers": [1, 2, 3]}
by_constructor = dict(source)
by_method = source.copy()
by_constructor["name"] = "Holmes"
by_constructor["numbers"][1] = 4
print(source)
print(by_constructor)
print(by_method)
{'name': 'Sherlock', 'numbers': [1, 4, 3]}
{'name': 'Holmes', 'numbers': [1, 4, 3]}
{'name': 'Sherlock', 'numbers': [1, 4, 3]}

Wähle eine der beiden Formen für flache Kopien, wenn das äußere Mapping unabhängig sein soll und gemeinsam genutzte verschachtelte Werte in Ordnung sind. Eine flache Kopie kopiert verschachtelte Objekte nicht rekursiv. Wenn du beispielsweise by_constructor["name"] einen anderen Wert zuweist, bleibt der name-Wert der Quelle unverändert, da dieser Schlüssel zu jedem der getrennten äußeren Dictionarys gehört. Eine Änderung an einem Element von numbers ist dagegen in allen drei ausgegebenen Dictionarys sichtbar, weil die Liste selbst gemeinsam genutzt wird. Dasselbe gilt, wenn ein Wert ein weiteres Dictionary ist: Die Kopie auf oberster Ebene behält eine Referenz auf dieses innere Dictionary. Wenn du nur einen einzelnen verschachtelten Wert unabhängig machen möchtest, kannst du diesen Wert separat kopieren. Eine tiefe Kopie eignet sich, wenn die gesamte verschachtelte Struktur unabhängig sein soll.

Flache Python-Dictionary-Kopie mit eigenem äußeren Dictionary

Ein verschachteltes Dictionary tief kopieren

Wenn auch verschachtelte veränderliche Werte unabhängig kopiert werden müssen, verwende copy.deepcopy(). Die Funktion kopiert die enthaltenen Objekte rekursiv. So kann das folgende Beispiel ein Listenelement und einen Wert in einem inneren Dictionary ändern, ohne das Original zu verändern. Das ist nützlich für verschachtelte Daten, die du unabhängig bearbeiten möchtest; wenn verschachtelte Werte gemeinsam genutzt werden sollen, ist es nicht nötig.

import copy

source = {
    "numbers": [1, 2, 3],
    "address": {"city": "Miami"},
}
independent = copy.deepcopy(source)
independent["numbers"][1] = 4
independent["address"]["city"] = "Lexington"
print(source)
print(independent)
{'numbers': [1, 2, 3], 'address': {'city': 'Miami'}}
{'numbers': [1, 4, 3], 'address': {'city': 'Lexington'}}

Eine tiefe Kopie ist nützlich, wenn spätere Änderungen nicht zwischen der Quellstruktur und einer Arbeitskopie übertragen werden sollen, etwa wenn du eine Version verschachtelter Einstellungen unabhängig bearbeiten möchtest. Sie kopiert auch verschachtelte Container und nicht nur das äußere Dictionary. Deshalb bleiben oben sowohl die Liste als auch das innere Mapping address unverändert. Bei großen Strukturen kann eine tiefe Kopie mehr Zeit und Speicher benötigen als eine flache Kopie. Verwende sie daher, wenn unabhängige verschachtelte Objekte erforderlich sind. Python-Objekte können ihr Kopierverhalten anpassen, und manche Ressourcen lassen sich nicht sinnvoll duplizieren. Wenn du mit solchen Objekten arbeitest, lies die Dokumentation zum copy-Modul.

Entscheidend ist, welche Objekte gemeinsam genutzt werden sollen: Bei einer Zuweisung wird das gesamte Dictionary gemeinsam genutzt, eine flache Kopie trennt nur das äußere Dictionary, und eine tiefe Kopie trennt zusätzlich verschachtelte Objekte. Die Dokumentation zum copy-Modul erläutert, wie flache und tiefe Kopien mit zusammengesetzten Objekten und Objekten mit angepasstem Kopierverhalten umgehen.