Ondiep en diep kopiëren in Python begrijpen
Python biedt verschillende efficiënte benaderingen om gegevens te beheren. Het begrijpen van concepten voor ondiepe en diepe kopieën is cruciaal bij het werken met gegevensstructuren zoals geneste lijsten, woordenboeken of aangepaste objecten.
Met zowel ondiep als diep kopiëren kunnen duplicaten van complexe gegevensstructuren worden gemaakt, hoewel hun gedrag verschilt als het gaat om hiërarchische gegevens.
Ondiepe kopie gebruiken
Een ondiepe kopie maakt een replica van de primaire structuur van het oorspronkelijke object, wat betekent dat als het oorspronkelijke item ingesloten objecten bevat, het duplicaat zal verwijzen naar dezelfde ingesloten objecten als het oorspronkelijke. In wezen reproduceert het maken van een ondiepe kopie van een entiteit de ordening op het hoogste niveau, in plaats van alle ingesloten objecten erin.
Om een oppervlakkige kopie van een object in Python te maken, kan ofwel de module copy
copy()
functie gebruikt worden, of de methode .copy()
op het object zelf.
Laten we ons verdiepen in een illustratie die het omgaan met lijsten en woordenboeken in de programmeertaal Python demonstreert.
import copy
main_list = [29, 49, ["Q", "R"]]
shallow_copy = copy.copy(main_list)
# Modify the nested list
shallow_copy[2][0] = 99
main_list[2][1] = 100
print(f"The main list: {main_list}")
print(f"The shallow copy list: {shallow_copy}")
In het gegeven codefragment wordt de variabele main_list
gedefinieerd als een muteerbare sequentie-achtige structuur die twee elementen van verschillende gegevenstypen bevat, namelijk een lijst van gehele getallen en een geneste lijst bestaande uit tekens. Het doel van deze code lijkt het maken van een kopie van de genoemde main_list
, aangeduid door de variabelenaam shallow_copy
. Deze bewerking zorgt ervoor dat de originele main_list
ongewijzigd blijft, terwijl wijzigingen in de gekopieerde versie erin worden gereflecteerd.
De wijzigingen aan de elementen in de oppervlakkig gekopieerde sublijst, die slechts dient als verwijzing naar de oorspronkelijke hoofdlijst, worden weerspiegeld in zowel de sublijst als de corresponderende hoofdlijst, wat de onderlinge verbondenheid illustreert.
Daarentegen hebben wijzigingen aan de perifere elementen (d.w.z. de gehele getallen) binnen de deep copy of de primaire lijst alleen invloed op die specifieke instantie. Het is belangrijk om op te merken dat deze externe entiteiten op zichzelf staande entiteiten zijn en niet moeten worden beschouwd als louter aanduidingen.
import copy
main_list = [29, 49, ["Q", "R"]]
shallow_copy = copy.copy(main_list)
# Modify the outer items
shallow_copy[0] = "M"
main_list[1] = "N"
print(f"The main list: {main_list}")
print(f"The shallow copy list: {shallow_copy}")
De resultaten geven aan dat de elementen binnen elke respectieve lijst niet onderling afhankelijk zijn, zoals blijkt uit hun individuele gedrag en interacties.
Bij het gebruik van woordenboeken geldt hetzelfde principe.
dict1 = {'ten': 10, 'twenty': 20, 'double':{'thirty': 30, 'sixty': 60}}
dict2 = dict1.copy()
# Modify inner and outer elements
dict1['double']['thirty'] = 30.00
dict1['ten'] = 10.00
print(f"The main dictionary, {dict1}")
print(f"The shallow copy dictionary, {dict2}")
De aanpassingen aan het diep geneste woordenboek dat zowel dict1
als dict2
omvat, hebben wederzijdse invloed. Omgekeerd hebben aanpassingen aan de externe componenten van dict1
uitsluitend invloed op de eigen staat.
Deep Copy gebruiken
Een deep copy creëert een onafhankelijke replica van het initiële object samen met al zijn ingesloten objecten, waardoor wordt voorkomen dat wijzigingen aan de een invloed hebben op de ander. Hierdoor kan elke instantie onafhankelijk worden gemanipuleerd zonder de toestand van een andere te beïnvloeden.
Om een exacte replica van een object in Python te maken, gebruik je de functionaliteit van de ingebouwde deepcopy()
functie die zich in de copy
module bevindt. Dit maakt het mogelijk om een nieuw object te maken met identieke attributen en eigenschappen als het origineel, terwijl geneste objecten of lijsten daarin behouden blijven.
Laten we eens kijken naar een scenario waarin we te maken hebben met een lijstgegevensstructuur.
import copy
main_list = [200, 300, ["I", "J"]]
deep_copy = copy.deepcopy(main_list)
# Modify the inner and outer list
deep_copy[2][0] = "K"
main_list[0] = 500
print(f"The main list: {main_list}")
print(f"The deep copy list: {deep_copy}")
In dit geval voert de code een diepgaande replicatie uit van de lijst met de naam main_list
, wat resulteert in de creatie van een autonome reproductie met de naam deep_copy
.
De wijziging van de binnenste of buitenste componenten binnen een diepe kopie heeft geen invloed op het origineel, noch op de gewijzigde versie. Dit illustreert dat de geneste elementen of externe componenten niet worden gedeeld tussen de twee instanties.
Werken met aangepaste objecten
Om een gepersonaliseerde entiteit te genereren, moet u eerst een Python-klasse definiëren die de kenmerken en attributen ervan belichaamt. Vervolgens instantieer je deze klasse om de individuele representatie voort te brengen.
Zeker, hier is een voorbeeld van het definiëren van een Book
klasse en het instantiëren ervan in Python:pythonclass Book:def init (self, title, author):self.title = titleself.author = authordef get_details(self):return f"Titel: {self.title}auteur: {self.author}“book1 = Book(“To Kill a Mockingbird”, “Harper Lee”)print(book1.get_details())Deze code definieert een Book
klasse met twee attributen ( title
en author
) en methoden om deze attributen in te stellen en informatie hierover op te halen met behulp van een getter methode genaamd get_details()
.Een instantie van deze klasse wordt dan aangemaakt door de
class Book:
def __init__(self, title, authors, price):
self.title = title
self.authors = authors
self.price = price
def __str__(self):
return f"Book(title='{self.title}', author='{self.authors}', \
price='{self.price}')"
module copy
aan te roepen om zowel een ondiepe kopie als een diepe kopie van een instantie van de klasse Book 839292923 aan te maken.
import copy
# Create a Book object
book1 = Book("How to All Things N Shallow Copy", \
["Bobby Jack", "Princewill Inyang"], 1000)
# Make a shallow copy
book2 = copy.copy(book1)
# Modify the original object
book1.authors.append("Yuvraj Chandra")
book1.price = 50
# Check the objects
print(book1)
print(book2)
Je kunt inderdaad opmerken dat wanneer een ondiepe kopie van een object wordt gemaakt, zoals in het geval van book2
dat wordt toegewezen aan book1
, het een afzonderlijke entiteit vormt van het bovenliggende object book1
. Ondanks dit onderscheid deelt book2
echter nog steeds bepaalde attributen met book1
, met name die in het binnenste object, namelijk het veld authorList
. Dientengevolge zullen alle wijzigingen die worden aangebracht in de laatste worden weerspiegeld in beide instanties, d.w.z. boek1
en boek2
. Aan de andere kant hebben wijzigingen die worden toegepast op de buitenste laag van de objecthiërarchie, zoals het kenmerk prijs
in ons voorbeeld, alleen invloed op de oorspronkelijke instantie, die in dit scenario verwijst naar boek1
.
Als alternatief genereert het produceren van een diepgaande replica een zelfvoorzienende versie van de oorspronkelijke entiteit, die duplicaten bevat van elk element dat erin is opgenomen.
# Create a Book object
book1 = Book("Why All Things N Deep Copy?", \
["Bobby Jack", "Yuvraj Chandra"], 5000)
# Make a deep copy
book2 = copy.deepcopy(book1)
# Modify the original object
book1.authors.append("Princewill Inyang")
book1.price = 60
# Check the objects
print(book1)
print(book2)
In dit geval vormt de diepgaande replicatie (boek2) een volledig autonome entiteit en hebben wijzigingen aan het bronobject (boek1) er geen invloed op.
Toepassingen voor oppervlakkige en diepe kopieën
Om informatie effectief te beheren, is het essentieel om zowel diepgaande als oppervlakkige reproducties te begrijpen. Door dit te doen, kan men onderscheiden wanneer men een diepere of beperktere vorm van replicatie moet gebruiken om gegevens nauwkeurig te manipuleren. Bepaalde situaties vragen om specifieke methoden, zoals hieronder beschreven:
Als je met ingewikkelde structuren werkt, kan een “oppervlakkige kopie” een effectieve strategie zijn om die structuur te dupliceren met behoud van de integriteit van de ingesloten componenten. In tegenstelling tot een “diepe kopie”, waarbij elk ondergeschikt element nauwgezet opnieuw moet worden gemaakt, bespaart deze methode tijd en geheugen door zo’n uitgebreide duplicatie te vermijden.
Een oppervlakkige reproductie van de status van een entiteit behouden, waarbij bepaalde gedeelde basisinformatie tussen het initiële item en zijn replica behouden blijft, terwijl ook verschillende geheugenruimtes in de gedupliceerde instanties mogelijk zijn.
Wanneer het creëren van een gewijzigde versie van een object gewenst is zonder de oorspronkelijke staat aan te tasten, kan een diepe kopie worden gebruikt. Deze techniek produceert afzonderlijke en autonome duplicaten van ingewikkeld gestructureerde objecten, waardoor wordt gegarandeerd dat wijzigingen aan de kopie geen invloed hebben op de oorspronkelijke instantie.
Een diepe replicatie is cruciaal in situaties waar meerdere verschillende iteraties van complexe hiërarchische gegevensstructuren nodig zijn, in het bijzonder die waarbij iteratieve of ingewikkelde objectarrangementen betrokken zijn.
Prestaties en overwegingen
Ondiep kopiëren creëert geen afzonderlijke instanties voor geneste objecten, wat resulteert in een efficiëntere prestatie met minder geheugengebruik in vergelijking met diep kopiëren. Desondanks kan deze aanpak leiden tot onbedoelde gevolgen door wijzigingen die worden aangebracht op gedeelde interne elementen tussen de originele en gekopieerde objecten.
Voor bijzonder grote en complexe gegevensstructuren kan het uitvoeren van een diepe kopie via recursie resulteren in een verminderde efficiëntie als gevolg van een verhoogde rekentijd en een verhoogd gebruik van bronnen. Desalniettemin garandeert deze methode een volledige scheiding tussen de originele en gekopieerde gegevens, waardoor de veiligheid bij het omgaan met ingewikkelde gegevensmanipulaties toeneemt.
De beste kopieeroptie voor je gegevens
Een goed begrip van de begrippen oppervlakkige en diepgaande replicatie is essentieel om informatie effectief te beheren zonder ongewenste resultaten. Als je deze ideeën begrijpt, kun je gegevens verwerken zonder nadelige gevolgen.
Door gebruik te maken van zowel oppervlakkige als diepe kopieertechnieken is men in staat om de meest geschikte methode te bepalen voor het veilig repliceren van hun datastructuren. Door de impact op deze gegevens te begrijpen, kan een grotere mate van betrouwbaarheid en voorspelbaarheid worden bereikt in de resultaten die door de code worden geproduceerd.