Ibland vill du ha en fullständig kopia av ett objekt, andra gånger vill du att det ska använda referenser. Se skillnaderna i handling.
Python erbjuder flera effektiva metoder för att hantera data. Att förstå grunda och djupa kopieringskoncept är avgörande när man arbetar med datastrukturer som kapslade listor, ordböcker eller anpassade objekt.
Både ytlig och djup kopia låter dig göra repliker av datastrukturer, men de fungerar annorlunda när det gäller kapslade data.
Använder Shallow Copy
Grund kopia fungerar genom att skapa en kopia av toppnivåstrukturen för originalobjektet. Detta betyder att om originalobjektet innehåller kapslade objekt kommer kopian att referera till samma kapslade objekt som originalet gör. Med andra ord, att göra en ytlig kopia av ett objekt duplicerar dess yttersta struktur, inte några kapslade objekt som det kan innehålla.
För att utföra en ytlig kopia i Python kan du använda kopieringsmodulens kopiera() funktion eller .kopiera() metod på objektet.
Ta ett exempel på arbetar med en lista eller ordbok i Python.
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}")
I koden ovan visas huvudlista variabeln innehåller en lista som innehåller heltal och en inre lista (kapslade objekt) som innehåller bokstäver. Kopieringsfunktionen skapar en kopia av huvudlista som koden lagrar i en annan variabel, grunt_kopia.
Alla ändringar du gör i grunt_kopia kapslad lista kommer också att direkt påverka listan huvudlista och vice versa. Dessa ändringar visar att den kapslade eller inre listan över grunt_kopia är bara en referens till det huvudlista, vilket gör att ändringarna gäller i huvudlista för.
Under tiden, alla ändringar som gjorts i de yttre objekten (heltalen) i antingen grunt_kopia eller huvudlista kommer bara att påverka det fallet. Dessa yttre föremål är oberoende värden i sig själva, inte bara referenser.
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}")
Resultatet visar att de båda listans yttre objekt är oberoende av varandra:
Samma idé gäller när man arbetar med ordböcker.
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}")
Ändringar gjorda i den kapslade ordboken för dikt1 påverka båda dikt1 och dikt2. Samtidigt ändras de yttre föremålen av dikt1 påverkar bara den.
Använder Deep Copy
Istället för att referera till de kapslade objekten i originalkopian, gör en djupkopia en helt separat kopia av originalobjektet och dess kapslade objekt. Ändring av den djupa kopian kommer inte att påverka originalobjektet och vice versa; de är verkligen separata värden.
För att göra en djup kopia i Python, använd deepcopy() kopieringsmodulens funktion.
Tänk på ett exempel på att arbeta med en lista.
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}")
Här utför koden en djup kopia av huvudlista, skapa en oberoende kopia med namnet deep_copy.
När du ändrar den kapslade listan eller yttre objekt i deep_copy, dina ändringar påverkar inte den ursprungliga listan, och vice versa. Detta visar att den kapslade listan eller de yttre elementen inte delas mellan de två kopiorna.
Arbeta med anpassade objekt
Du kan skapa ett anpassat objekt genom att definiera en Python-klass och skapa en instans av klassen.
Här är ett exempel på att skapa ett enkelt objekt från en bok klass:
classBook:
def__init__(self, title, authors, price):
self.title = title
self.authors = authors
self.price = price
def__str__(self):
returnf"Book(title='{self.title}', author='{self.authors}', \
price='{self.price}')"
Gör nu både en ytlig kopia och en djup kopia av en instans av detta bok klass med hjälp av kopiera modul.
import copy
# Create a Book object
book1 = Book("How to MakeUseOf 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)
Som du kan se, den grunda kopian (bok 2) är ett nytt objekt, men det refererar till samma inre objekt (författarlista) som det ursprungliga objektet (bok1). Därför påverkar en ändring av originalobjektets författare båda instanserna (bok1 och bok2), medan en ändring av det yttre objektet (pris) påverkar endast det ursprungliga objektet (bok1).
Å andra sidan skapar en djupkopia en oberoende kopia av originalobjektet, inklusive kopior av alla objekt som finns i det.
# Create a Book object
book1 = Book("Why MakeUseOf 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)
I det här fallet, den djupa kopian (bok 2) är ett helt oberoende objekt och modifierar det ursprungliga objektet (bok1) påverkar det inte.
Används för Shallow Copy och Deep Copy
Det är viktigt att förstå djup och ytlig kopia så att du kan välja lämplig metod för att manipulera data. Här är några scenarier där varje metod är tillämplig:
- Använd en ytlig kopia om du vill replikera ett komplext objekt utan att generera nya instanser av dess kapslade objekt. Detta tillvägagångssätt är mer minneseffektivt och snabbare än djupkopiering eftersom det inte duplicerar kapslade objekt.
- Använd en ytlig kopia för att skapa en ögonblicksbild av ett objekts tillstånd samtidigt som du delar vissa underliggande data mellan det ursprungliga och det kopierade objektet.
- Använd en djupkopia om du vill ändra en replik av ett objekt utan att påverka originalet. Detta genererar oberoende kopior av kapslade objekt, vilket säkerställer att eventuella ändringar av kopian inte gäller originalet.
- Djupkopiering är avgörande när du behöver oberoende kopior av kapslade datastrukturer, främst när du hanterar rekursiva eller intrikata objekthierarkier.
Prestanda och överväganden
Eftersom ytlig kopia inte genererar nya instanser av kapslade objekt, går den vanligtvis snabbare och använder mindre minne än djupkopia. Originalet och den grunda kopian kan dock ha oönskade bieffekter av att ändra delade interna föremål.
Särskilt för stora och djupt kapslade datastrukturer, djupkopiering, ett rekursivt förfarande, kan vara långsammare och använda mer minne. Det säkerställer dock totalt oberoende mellan originalet och det djupa duplikatet, vilket gör intrikat datamanipulation säkrare.
Det bästa kopieringsalternativet för dina data
Många programmeringsspråk använder konceptet ytlig och djup kopia. Genom att förstå det kan du manipulera data utan oförutsedda konsekvenser.
Genom att använda grunda och djupa kopieringstekniker kan du välja det bästa sättet att duplicera dina datastrukturer på ett säkert sätt. Genom att förstå effekterna på din data får du mer pålitliga och förutsägbara resultat av din kod.