In Python wordt de gegevensstructuur dict vaak gebruikt om geneste informatie op te slaan. Ontwikkelaars komen vaak de noodzaak tegen om dergelijke structuren te klonen bij het werken met sjablonen, configuraties of het doorgeven van gegevens tussen onderdelen van een applicatie.
Standaard kopiëren van een dict met behulp van toekenning (=) creëert alleen een verwijzing naar het oorspronkelijke object. Shallow copy kopieert het dict-object zelf, maar niet de geneste objecten. Deep copy kopieert recursief alle objecten binnenin, wat voorkomt dat wijzigingen in de ene kopie invloed hebben op de andere.
Voor shallow copy kan dict.copy() of de constructor dict() worden gebruikt, voor deep copy de module copy en de functie deepcopy():
import copy d = {"a": 1, "b": {"c": 2}} shallow_d = d.copy() deep_d = copy.deepcopy(d) # Nu zal wijziging in shallow_d['b']['c'] invloed hebben op d['b']['c'] # wijziging in deep_d['b']['c'] heeft geen invloed op de oorspronkelijke dictionary
Belangrijke kenmerken:
Kan dict.copy() dieper dan het eerste niveau kopiëren?
Nee, dict.copy() creëert alleen een shallow copy. Geneste dictionaries zullen nog steeds verwijzingen zijn naar dezelfde objecten als in de oorspronkelijke dict.
Als er een onveranderbaar object in de structuur is (bijvoorbeeld een tuple), zal deepcopy het dan diep kopiëren?
Deepcopy kopieert alleen veranderbare geneste objecten. Onveranderbare objecten blijven hetzelfde — tuples, strings en getallen worden niet recursief gekopieerd, maar gewoon naar de kopie overgebracht.
Kan serialisatie via json.loads(json.dumps(dict)) worden gebruikt voor deep copy?
Dat kan, maar met voorbehouden. Deze manier werkt alleen voor serializeerbare types en is niet geschikt als er onveranderbare objecten (zoals functies of aangepaste klassen) in de dictionary staan:
import json orig = {"a": 10, "b": [1,2,3]} copy_like_deep = json.loads(json.dumps(orig)) # Werkt niet voor complexe objecten
Negatieve case
Een ontwikkelaar kloont instellingen via copy(), verandert vervolgens een genest waarde, denkend dat dit twee onafhankelijke structuren zijn.
Voordelen:
Eenvoudig en snel
Nadelen:
Wijzigingen in geneste objecten in één kopie spiegel zich in alle weer — bugs die moeilijk te debuggen zijn.
Positieve case
Een ontwikkelaar gebruikt altijd copy.deepcopy() voor geneste structuren, zelfs als de oorspronkelijke dict vlak lijkt.
Voordelen:
Data onafhankelijkheid is gegarandeerd, bugs zijn tot een minimum beperkt
Nadelen:
Deepcopy is langzamer en verbruikt meer geheugen, soms is het overbodig.