
In Python, puoi creare una copia superficiale e profonda con il metodo copy() di list , dictionary, ecc., o le funzioni copy() e deepcopy() del modulo copy.
In questo articolo vengono descritti i seguenti contenuti.
- Copia superficiale e copia profonda in Python
- Assegnazione ad un’altra variabile
- Copia poco profonda:
copy(), copy.copy(), etc.
- copy() metodo di elenco, dizionario, ecc.
- Fetta
- list(), dict(), ecc.
- copia.copia()
- Copia profonda:
copy.deepcopy()
Di seguito è riportato un riepilogo delle differenze tra l’assegnazione a un’altra variabile, la copia superficiale e la copia profonda.
import copy
l = [0, 1, [2, 3]]
l_assign = l # assignment
l_copy = l.copy() # shallow copy
l_deepcopy = copy.deepcopy(l) # deep copy
l[1] = 100
l[2][0] = 200
print(l)
# [0, 100, [200, 3]]
print(l_assign)
# [0, 100, [200, 3]]
print(l_copy)
# [0, 1, [200, 3]]
print(l_deepcopy)
# [0, 1, [2, 3]]
Copia superficiale e copia profonda in Python
La documentazione ufficiale di Python descrive la copia superficiale e la copia profonda come segue.
La differenza tra la copia superficiale e quella profonda è rilevante solo per gli oggetti composti (oggetti che contengono altri oggetti, come elenchi o istanze di classe):
Per gli oggetti in oggetti mutabili come elenchi e dizionari (= elementi in un elenco o valori in un dizionario), la copia superficiale inserire i riferimenti e la copia profonda inserendo le copie. Nel caso dei riferimenti, sono lo stesso oggetto, quindi se uno di essi viene modificato, viene modificato anche l’altro.
Assegnazione ad un’altra variabile
Per prima cosa, vediamo cosa succede quando si assegna a una variabile.
Quando un oggetto mutabile come un elenco o un dizionario viene assegnato a più variabili, l’aggiornamento di una variabile (= modifica, aggiunta o eliminazione di elementi, ecc.) aggiornerà anche le altre variabili.
l1 = [0, 1, [2, 3]]
l2 = l1
print(l1 is l2)
# True
l1[1] = 100
l1[2][0] = 200
print(l1)
# [0, 100, [200, 3]]
print(l2)
# [0, 100, [200, 3]]
print(l1 is l2)
# True
Come puoi vedere dal risultato di is, le due variabili si allo stesso oggetto sia prima che valore la modifica del.
Per una copia invece di un riferimento dello stesso oggetto, utilizzare il metodo copy() o la funzione copy.deepcopy() descritto di seguito.
D’altra parte, nel caso di oggetti immutabili come numeri int, float e strings str, il valore dell’oggetto non può essere aggiornato. Quando assegnate, le due variabili sono lo stesso oggetto, ma quando una viene aggiornata a un nuovo valore, diventa un oggetto diverso e l’altra rimane la stessa.
i1 = 1
i2 = i1
print(i1 is i2)
# True
i1 += 100
print(i1)
# 101
print(i2)
# 1
print(i1 is i2)
# False
Copia poco profonda:copy(), copy.copy(), etc.
copy() metodo di elenco, dizionario, ecc.
Il metodo copy() viene fornito per elenchi, dizionari, ecc. Il metodo copy() esegue una copia superficiale.
Come accennato in precedenza, una copia superficiale in un riferimento a un oggetto nell’oggetto originale. Ad esempio, nel caso di una copia superficiale di un elenco, l’elenco stesso è un oggetto diverso, ma i suoi elementi sono riferimenti agli stessi oggetti negli elementi dell’elenco originale.
l = [0, 1, [2, 3]]
l_copy = l.copy()
print(l is l_copy)
# False
print(l[2] is l_copy[2])
# True
Pertanto, se gli elementi sono mutevoli, quando uno viene aggiornato, viene aggiornato anche l’altro. Nel caso di un immutabile, quando viene aggiornato a un nuovo valore, diventa un oggetto diverso e l’altro rimane l’originale.
l[1] = 100
l[2][0] = 200
print(l)
# [0, 100, [200, 3]]
print(l_copy)
# [0, 1, [200, 3]]
print(l[2] is l_copy[2])
# True
Lo stesso vale non solo per un elenco di elenchi come nell’esempio sopra, ma anche per un elenco di dizionari, ma anche per un elenco di dizionari (un dizionario che ha dizionari come valori), ecc.
Fetta
Anche le fette per i tipi di sequenza mutabili, come gli elenchi, creano copie superficiali.
Ad esempio, l’applicazione della sezione [:] che specifica tutti gli elementi crea una copia superficiale dell’intero elenco.
l = [0, 1, [2, 3]]
l_whole_slice = l[:]
l[1] = 100
l[2][0] = 200
print(l)
# [0, 100, [200, 3]]
print(l_whole_slice)
# [0, 1, [200, 3]]
Poiché il metodo copy() è stato aggiunto ai tipi di sequenza mutabili in Python 3.3, la tecnica di creare una copia superficiale con [:] è stato spesso utilizzato in precedenza. Per il nuovo codice, sarebbe meglio usare il metodo copy() per rendere più chiare le tue intenzioni.
Una fetta per una parte fa anche una copia superficiale.
l = [0, 1, [2, 3]]
l_slice = l[1:]
print(l_slice)
# [1, [2, 3]]
l[1] = 100
l[2][0] = 200
print(l)
# [0, 100, [200, 3]]
print(l_slice)
# [1, [200, 3]]
Se vuoi fare una copia profonda, puoi usare la funzione copy.deepcopy() per la sezione.
list(), dict(), ecc.
Puoi fare una copia superficiale di una lista o di un dizionario passando una lista a list() o un dizionario a dict().
l = [0, 1, [2, 3]]
l_list = list(l)
l[1] = 100
l[2][0] = 200
print(l)
# [0, 100, [200, 3]]
print(l_list)
# [0, 1, [200, 3]]
copia.copia()
È anche possibile eseguire una copia superficiale con la funzione copy() del modulo di copia.
l = [0, 1, [2, 3]]
l_copy = copy.copy(l)
l[1] = 100
l[2][0] = 200
print(l)
# [0, 100, [200, 3]]
print(l_copy)
# [0, 1, [200, 3]]
Usa copy.copy() se vuoi fare una copia superficiale di un oggetto per il quale non è fornito il metodo copy().
Copia profonda:copy.deepcopy()
Per fare una copia profonda, usa la funzione deepcopy() del modulo copy.
l = [0, 1, [2, 3]]
l_deepcopy = copy.deepcopy(l)
print(l is l_deepcopy)
# False
print(l[2] is l_deepcopy[2])
# False
l[1] = 100
l[2][0] = 200
print(l)
# [0, 100, [200, 3]]
print(l_deepcopy)
# [0, 1, [2, 3]]
In una copia profonda, le copie vengono inserite al posto dei riferimenti agli oggetti, quindi la modifica di una non cambia l’altra.
Quello che segue è un esempio di applicazione della funzione deepcopy() a una sezione.
l = [0, 1, [2, 3]]
l_slice_deepcopy = copy.deepcopy(l[1:])
print(l_slice_deepcopy)
# [1, [2, 3]]
l[1] = 100
l[2][0] = 200
print(l)
# [0, 100, [200, 3]]
print(l_slice_deepcopy)
# [1, [2, 3]]