Comprensione della copia superficiale e profonda in Python

Comprensione della copia superficiale e profonda in Python
I lettori come te aiutano a sostenere MUO. Quando effettui un acquisto utilizzando i link sul nostro sito, potremmo guadagnare una commissione di affiliazione. Per saperne di più.

Python offre diversi approcci efficienti alla gestione dei dati. Comprendere i concetti di copia superficiale e approfondita è fondamentale quando si lavora con strutture di dati come elenchi nidificati, dizionari o oggetti personalizzati.





MUO Video della giornata SCORRI PER CONTINUARE CON IL CONTENUTO

Sia la copia superficiale che quella profonda consentono di creare repliche di strutture dati, ma agiscono in modo diverso per quanto riguarda i dati nidificati.





Utilizzo della copia superficiale

La copia superficiale funziona creando una copia della struttura di primo livello dell'oggetto originale. Ciò significa che, se l'oggetto originale contiene oggetti nidificati, la copia farà riferimento agli stessi oggetti nidificati dell'originale. In altre parole, fare una copia superficiale di un oggetto ne duplica la struttura più esterna, non gli oggetti annidati che potrebbe contenere.





Per eseguire una copia superficiale in Python, puoi utilizzare il modulo copy copia() funzione o il .copia() metodo sull'oggetto.

come eliminare i vecchi aggiornamenti di Windows?

Considera un esempio di lavorare con un elenco o un dizionario in 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}")

Nel codice sopra, il lista_principale La variabile contiene una lista contenente numeri interi e una lista interna (oggetto annidato) contenente lettere. La funzione di copia crea una copia del file lista_principale che il codice memorizza in un'altra variabile, superficiale_copia .

Qualsiasi modifica apportata al file superficiale_copia L'elenco nidificato influenzerà direttamente anche quello del file lista_principale e viceversa. Queste modifiche mostrano che l'elenco nidificato o interno del file superficiale_copia è solo un riferimento a quello di lista_principale , rendendo applicabili le modifiche lista_principale pure.





  modifiche all'elenco nidificato della copia superficiale

Nel frattempo, qualsiasi modifica apportata agli elementi esterni (i numeri interi) in entrambi superficiale_copia O lista_principale influenzerà solo quell'istanza. Questi elementi esterni sono valori indipendenti di per sé, non semplici riferimenti.

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

L'output dimostra che gli elementi esterni di entrambi gli elenchi sono indipendenti l'uno dall'altro:





  modifiche agli elementi esterni di copia superficiale

La stessa idea vale quando si lavora con i dizionari.

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

Modifiche apportate al dizionario nidificato di dict1 influenzano entrambi dict1 E dict2 . Allo stesso tempo, modifiche agli elementi esterni di dict1 influiscono solo su quello.

  utilizzando la copia superficiale con dizionario nidificato

Utilizzo della copia approfondita

Invece di fare riferimento agli oggetti nidificati della copia originale, una copia profonda crea una copia completamente separata dell'oggetto originale e dei suoi oggetti nidificati. La modifica della copia profonda non influirà sull'oggetto originale e viceversa; sono valori veramente separati.

Per creare una copia approfondita in Python, utilizzare il file copia profonda() funzione del modulo di copia.

Considera un esempio di lavoro con un elenco.

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

Qui, il codice esegue una copia approfondita di lista_principale , creando una copia indipendente denominata deep_copy .

Quando modifichi l'elenco nidificato o gli elementi esterni nel file deep_copy , le modifiche non influiscono sull'elenco originale e viceversa. Ciò dimostra che l'elenco nidificato o gli elementi esterni non sono condivisi tra le due copie.

  utilizzando la copia profonda con elenco nidificato

Lavorare con oggetti personalizzati

Puoi creare un oggetto personalizzato tramite definire una classe Python e creando un'istanza della classe.

Ecco un esempio di creazione di un oggetto semplice da a Libro classe:

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

Ora, crea sia una copia superficiale che una copia approfondita di un'istanza di questo Libro classe utilizzando il file copia modulo.

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)

Come puoi vedere, la copia superficiale ( libro2 ) è un nuovo oggetto, ma fa riferimento allo stesso oggetto interno (elenco degli autori) dell'oggetto originale ( libro1 ). Pertanto, una modifica agli autori dell'oggetto originale influisce su entrambe le istanze (book1 e book2), mentre una modifica all'elemento esterno ( prezzo ) influisce solo sull'oggetto originale ( libro1 ).

  utilizzando la copia superficiale con oggetto personalizzato

D'altro canto, la creazione di una copia profonda crea una copia indipendente dell'oggetto originale, comprese le copie di tutti gli oggetti in esso contenuti.

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

In questo caso, la copia profonda ( libro2 ) è un oggetto completamente indipendente e la modifica dell'oggetto originale ( libro1 ) non lo influenza.

  utilizzando la copia approfondita con oggetto personalizzato

Usi per Copia superficiale e Copia approfondita

È fondamentale comprendere la copia profonda e superficiale in modo da poter selezionare l'approccio appropriato per la manipolazione dei dati. Ecco alcuni scenari in cui ciascun metodo è applicabile:

  • Utilizza una copia superficiale se desideri replicare un oggetto complesso senza generare nuove istanze dei suoi oggetti nidificati. Questo approccio è più efficiente in termini di memoria e più veloce della copia approfondita perché non duplica oggetti nidificati.
  • Utilizza una copia superficiale per creare un'istantanea dello stato di un oggetto pur condividendo alcuni dati sottostanti tra gli oggetti originali e copiati.
  • Utilizza una copia approfondita se desideri modificare una replica di un oggetto senza influire sull'originale. Ciò genera copie indipendenti di oggetti nidificati, garantendo che eventuali modifiche alla copia non si applichino all'originale.
  • La copia approfondita è fondamentale quando sono necessarie copie indipendenti di strutture dati nidificate, principalmente quando si ha a che fare con gerarchie di oggetti ricorsive o complesse.

Prestazioni e considerazioni

Poiché la copia superficiale non genera nuove istanze di oggetti annidati, in genere viene eseguita più velocemente e utilizza meno memoria rispetto alla copia approfondita. Tuttavia, l'originale e la copia superficiale potrebbero avere effetti collaterali indesiderati derivanti dalla modifica degli elementi interni condivisi.

In particolare per strutture dati grandi e profondamente annidate, deep copy, una procedura ricorsiva , può essere più lento e utilizzare più memoria. Tuttavia, garantisce la totale indipendenza tra l'originale e il duplicato profondo, rendendo più sicura la manipolazione complessa dei dati.

La migliore opzione di copia per i tuoi dati

Molti linguaggi di programmazione utilizzano il concetto di copia superficiale e profonda. Comprenderlo consente di manipolare i dati senza conseguenze impreviste.

Utilizzando tecniche di copia superficiale e profonda, puoi selezionare l'approccio migliore per duplicare le tue strutture dati in modo sicuro. Comprendendo gli effetti sui tuoi dati, otterrai risultati più affidabili e prevedibili dal tuo codice.