Uneori, veți dori o copie completă a unui obiect, alteori veți dori ca acesta să folosească referințe. Vedeți diferențele în acțiune.

Python oferă mai multe abordări eficiente pentru gestionarea datelor. Înțelegerea conceptelor de copiere superficială și profundă este crucială atunci când lucrați cu structuri de date precum liste imbricate, dicționare sau obiecte personalizate.

Atât copierea superficială, cât și cea profundă vă permit să faceți replici ale structurilor de date, dar acestea acționează diferit în ceea ce privește datele imbricate.

Utilizarea copierii superficiale

Copia superficială funcționează prin crearea unei copii a structurii de nivel superior a obiectului original. Aceasta înseamnă că, dacă obiectul original conține obiecte imbricate, copia va face referire la aceleași obiecte imbricate ca și originalul. Cu alte cuvinte, realizarea unei copii superficiale a unui obiect dublează structura sa cea mai exterioară, nu orice obiecte imbricate pe care le poate conține.

Pentru a efectua o copie superficială în Python, puteți utiliza modulul de copiere

instagram viewer
copie() funcția sau .copie() metoda asupra obiectului.

Luați în considerare un exemplu de lucrul cu o listă sau un dicționar în 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}")

În codul de mai sus, listă_principală variabila deține o listă care conține numere întregi și o listă interioară (obiect imbricat) care conține litere. Funcția de copiere creează o copie a fișierului listă_principală pe care codul le stochează într-o altă variabilă, copie_pe_profundă.

Orice modificări pe care le faceți la copie_pe_profundă lista imbricată va afecta, de asemenea, direct pe cea a listă_principală si invers. Aceste modificări arată că lista imbricată sau interioară a copie_pe_profundă este doar o referire la cea a listă_principală, aplicând modificările în listă_principală de asemenea.

Între timp, orice modificări aduse elementelor exterioare (întregi) în oricare dintre acestea copie_pe_profundă sau listă_principală va afecta doar acea instanță. Aceste elemente exterioare sunt valori independente în sine, nu doar simple referințe.

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}")

Rezultatul demonstrează că ambele elemente exterioare ale listei sunt independente unele de altele:

Aceeași idee se aplică atunci când lucrați cu dicționare.

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}")

Modificări aduse dicționarului imbricat al dict1 afectează pe amândouă dict1 și dict2. În același timp, modificări la elementele exterioare ale dict1 afectează numai ea.

Folosind Deep Copy

În loc să facă referire la obiectele imbricate ale copiei originale, o copie profundă face o copie complet separată a obiectului original și a obiectelor sale imbricate. Modificarea copiei adânci nu va afecta obiectul original și invers; sunt cu adevărat valori separate.

Pentru a face o copie profundă în Python, utilizați deepcopy() funcția modulului de copiere.

Luați în considerare un exemplu de lucru cu o listă.

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}")

Aici, codul realizează o copie profundă a listă_principală, creând o copie independentă numită deep_copy.

Când modificați lista imbricată sau elementele exterioare din deep_copy, modificările dvs. nu afectează lista originală și invers. Acest lucru demonstrează că lista imbricată sau elementele exterioare nu sunt partajate între cele două copii.

Lucrul cu obiecte personalizate

Puteți crea un obiect personalizat prin definirea unei clase Python și crearea unei instanțe a clasei.

Iată un exemplu de creare a unui obiect simplu din a Carte clasă:

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}')"

Acum, faceți atât o copie superficială, cât și o copie profundă a unei instanțe a acesteia Carte clasa folosind copie 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)

După cum puteți vedea, copia superficială (cartea 2) este un obiect nou, dar face referire la același obiect interior (lista de autori) ca și obiectul original (cartea 1). Prin urmare, o modificare a autorilor obiectului original afectează ambele instanțe (cartea 1 și cartea 2), în timp ce o modificare a articolului exterior (Preț) afectează doar obiectul original (cartea 1).

Pe de altă parte, realizarea unei copii profunde creează o copie independentă a obiectului original, inclusiv copii ale tuturor obiectelor conținute în acesta.

# 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)

În acest caz, copia adâncă (cartea 2) este un obiect complet independent și modificând obiectul original (cartea 1) nu îl afectează.

Utilizări pentru copiere superficială și copiere adâncă

Este vital să înțelegeți copierea profundă și superficială, astfel încât să puteți selecta abordarea adecvată pentru manipularea datelor. Iată câteva scenarii în care fiecare metodă este aplicabilă:

  • Utilizați o copie superficială dacă doriți să replicați un obiect complex fără a genera noi instanțe ale obiectelor imbricate ale acestuia. Această abordare este mai eficientă în memorie și mai rapidă decât copierea profundă, deoarece nu dublează obiectele imbricate.
  • Utilizați o copie superficială pentru a crea un instantaneu al stării unui obiect, în timp ce partajați unele date subiacente între obiectele originale și cele copiate.
  • Utilizați o copie profundă dacă doriți să modificați o replică a unui obiect fără a afecta originalul. Acest lucru generează copii independente ale obiectelor imbricate, asigurându-se că orice modificări aduse copiei nu se aplică originalului.
  • Copierea profundă este esențială atunci când aveți nevoie de copii independente ale structurilor de date imbricate, în principal atunci când aveți de-a face cu ierarhii de obiecte recursive sau complicate.

Performanță și considerații

Deoarece copierea superficială nu generează instanțe noi de obiecte imbricate, de obicei rulează mai rapid și utilizează mai puțină memorie decât copierea profundă. Cu toate acestea, originalul și copia superficială pot avea efecte secundare nedorite de la modificarea elementelor interne partajate.

În special pentru structurile de date mari și profund imbricate, copiere profundă, o procedură recursivă, poate fi mai lent și poate folosi mai multă memorie. Cu toate acestea, asigură independența totală între original și duplicatul profund, făcând manipularea complicată a datelor mai sigură.

Cea mai bună opțiune de copiere pentru datele dvs

Multe limbaje de programare folosesc conceptul de copiere superficială și profundă. Înțelegerea acestuia vă permite să manipulați datele fără consecințe neprevăzute.

Folosind tehnici de copiere superficială și profundă, puteți selecta cea mai bună abordare pentru a vă duplica structurile de date în siguranță. Înțelegând efectele asupra datelor dvs., veți obține rezultate mai sigure și mai previzibile din codul dvs.