Kartais norėsite visos objekto kopijos, o kartais norėsite, kad būtų naudojamos nuorodos. Pamatykite veiksmų skirtumus.
Python siūlo keletą efektyvių duomenų tvarkymo būdų. Dirbant su duomenų struktūromis, pvz., įdėtais sąrašais, žodynais ar pasirinktiniais objektais, labai svarbu suprasti seklios ir gilios kopijos sąvokas.
Tiek sekli, tiek gili kopija leidžia kurti duomenų struktūrų kopijas, tačiau įdėtųjų duomenų atžvilgiu jos veikia skirtingai.
Sekliosios kopijos naudojimas
Sekli kopija veikia sukuriant originalaus objekto aukščiausio lygio struktūros kopiją. Tai reiškia, kad jei originaliame objekte yra įdėtų objektų, kopijoje bus nuoroda į tuos pačius įdėtus objektus, kuriuos daro originalas. Kitaip tariant, darant negilią objekto kopiją dubliuojama jo atokiausia struktūra, o ne jokie įdėtieji objektai.
Norėdami atlikti seklią kopiją Python, galite naudoti kopijavimo modulį kopija () funkcija arba .copy() metodas objekte.
Apsvarstykite pavyzdį darbas su sąrašu ar žodynu 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}")
Aukščiau pateiktame kode pagrindinis_sąrašas kintamasis turi sąrašą, kuriame yra sveikieji skaičiai, ir vidinį sąrašą (įdėtą objektą), kuriame yra raidžių. Kopijavimo funkcija sukuria kopiją pagrindinis_sąrašas kurį kodas saugo kitame kintamajame, sekli_kopija.
Bet kokie jūsų atlikti pakeitimai sekli_kopija įdėtas sąrašas taip pat tiesiogiai paveiks sąrašą pagrindinis_sąrašas ir atvirkščiai. Šie pakeitimai rodo, kad įdėtas arba vidinis sąrašas sekli_kopija yra tik nuoroda į pagrindinis_sąrašas, kad pakeitimai būtų taikomi pagrindinis_sąrašas taip pat.
Tuo tarpu bet kokie išorinių elementų (sveikųjų skaičių) pakeitimai sekli_kopija arba pagrindinis_sąrašas turės įtakos tik tam atvejui. Šie išoriniai elementai yra savarankiškos vertybės, o ne tik nuorodos.
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}")
Išvestis parodo, kad abu sąrašo išoriniai elementai yra nepriklausomi vienas nuo kito:
Ta pati idėja galioja ir dirbant su žodynais.
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}")
Pakeitimai atlikti įdėtame žodyne diktas1 paveikti abu diktas1 ir diktas2. Tuo pačiu metu keičiasi išoriniai elementai diktas1 paveikti tik tai.
Deep Copy naudojimas
Užuot nuorodų į įdėtus originalios kopijos objektus, gilioji kopija sukuria visiškai atskirą originalaus objekto ir jo įdėtų objektų kopiją. Gilios kopijos modifikavimas neturės įtakos originaliam objektui ir atvirkščiai; tai tikrai atskiros vertybės.
Norėdami sukurti gilią kopiją Python, naudokite gili kopija () kopijavimo modulio funkcija.
Apsvarstykite darbo su sąrašu pavyzdį.
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}")
Čia kodas atlieka gilią kopiją pagrindinis_sąrašas, sukuriant nepriklausomą kopiją pavadinimu gilus_kopija.
Kai keičiate įdėtą sąrašą arba išorinius elementus gilus_kopija, jūsų pakeitimai neturi įtakos pradiniam sąrašui ir atvirkščiai. Tai parodo, kad įdėtas sąrašas arba išoriniai elementai nėra bendrinami tarp dviejų kopijų.
Darbas su pasirinktiniais objektais
Galite sukurti pasirinktinį objektą apibrėžiant Python klasę ir sukurti klasės egzempliorių.
Štai pavyzdys, kaip sukurti paprastą objektą iš a Knyga klasė:
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}')"
Dabar sukurkite negilią ir gilią šio egzemplioriaus kopiją Knyga klasė naudojant kopija modulis.
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)
Kaip matote, sekli kopija (knyga 2) yra naujas objektas, tačiau jis nurodo tą patį vidinį objektą (autorių sąrašą), kaip ir pradinis objektas (knyga1). Taigi pradinio objekto autorių pakeitimas turi įtakos abiem atvejais (1 knyga ir 2 knyga), o išorinio elemento pakeitimas (kaina) veikia tik pradinį objektą (knyga1).
Kita vertus, darant gilią kopiją sukuriama nepriklausoma originalaus objekto kopija, įskaitant visų jame esančių objektų kopijas.
# 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)
Šiuo atveju gilioji kopija (knyga 2) yra visiškai nepriklausomas objektas, keičiantis pradinį objektą (knyga1) tam įtakos neturi.
Naudojimas sekliajai kopijai ir giliajai kopijai
Labai svarbu suprasti gilią ir seklią kopiją, kad galėtumėte pasirinkti tinkamą duomenų apdorojimo būdą. Toliau pateikiami keli scenarijai, kai taikomas kiekvienas metodas:
- Naudokite seklią kopiją, jei norite pakartoti sudėtingą objektą negeneruodami naujų įdėtųjų objektų egzempliorių. Šis metodas yra efektyvesnis atmintyje ir greitesnis nei gilus kopijavimas, nes jis nedubliuoja įdėtų objektų.
- Naudokite negilią kopiją, kad sukurtumėte momentinę objekto būsenos nuotrauką, kartu dalindamiesi kai kuriais pagrindiniais duomenimis tarp originalaus ir nukopijuoto objektų.
- Naudokite giliąją kopiją, jei norite modifikuoti objekto kopiją nepaveikdami originalo. Taip sukuriamos nepriklausomos įdėtųjų objektų kopijos ir užtikrinama, kad bet kokie kopijos pakeitimai netaikomi originalui.
- Gilus kopijavimas yra labai svarbus, kai reikia nepriklausomų įdėtųjų duomenų struktūrų kopijų, ypač kai kalbama apie rekursines arba sudėtingas objektų hierarchijas.
Veikimas ir svarstymai
Kadangi sekli kopija nesukuria naujų įdėtųjų objektų egzempliorių, ji paprastai veikia greičiau ir sunaudoja mažiau atminties nei gilioji kopija. Tačiau originalas ir sekli kopija gali turėti nepageidaujamą šalutinį poveikį keičiant bendrinamus vidinius elementus.
Ypač didelėms ir giliai įterptoms duomenų struktūroms, giliajai kopijai, rekursinė procedūra, gali veikti lėčiau ir naudoti daugiau atminties. Tačiau tai užtikrina visišką nepriklausomybę tarp originalo ir gilaus dublikato, todėl sudėtingas duomenų manipuliavimas tampa saugesnis.
Geriausia jūsų duomenų kopijavimo parinktis
Daugelis programavimo kalbų naudoja seklios ir gilios kopijos sąvoką. Suprasdami tai, galite manipuliuoti duomenimis be nenumatytų pasekmių.
Naudodami sekliojo ir gilaus kopijavimo metodus, galite pasirinkti geriausią būdą saugiai kopijuoti duomenų struktūras. Suprasdami poveikį jūsų duomenims, sulauksite patikimesnių ir labiau nuspėjamų kodo rezultatų.