ProgrammatieBackend ontwikkelaar

Wat is het verschil tussen shallow en deep copy in de dict-structuur, en hoe kopieer je geneste dictionaries correct in Python?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

Geschiedenis van de vraag

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.

Probleem

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.

Oplossing

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:

  • Shallow copy kopieert alleen de eerste "laag" van het object
  • Deep copy kopieert recursief alle objecten binnen de structuur
  • Bij het werken met geneste structuren gebruik altijd deepcopy als volledige onafhankelijkheid van de kopie vereist is

Vragen met een addertje onder het gras.

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

Typische fouten en anti-patronen

  • Gebruik van eenvoudige toekenning in plaats van kopiëren
  • Toepassing van shallow copy op geneste structuren, wat leidt tot onverwachte wijzigingen in alle "kopieën"

Voorbeeld uit het leven

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.