il Prossimo Capitolo: Funzioni
Superficiale e Profonda Copia
Introduzione
Come abbiamo visto nel capitolo “Tipi di Dati e Variabili”, Python ha un comportamento strano – in confronto con altri linguaggi di programmazione – quando l’assegnazione e la copia di tipi di dati semplici come numeri interi e stringhe. La differenza tra la copia superficiale e profonda è rilevante solo per gli oggetti composti, che sono oggetti contenenti altri oggetti, come elenchi o istanze di classe.,
Nel seguente frammento di codice y punta alla stessa posizione di memoria di X. Questo cambia, quando assegniamo un valore diverso a y. In questo caso y riceverà una posizione di memoria separata, come abbiamo visto nel capitolo “Tipi di dati e variabili”.
>>> x = 3>>> y = x
Ma anche se questo comportamento interno appare strano rispetto a linguaggi di programmazione come C, C++ e Perl, tuttavia i risultati osservabili delle assegnazioni rispondono alle nostre aspettative. Ma può essere problematico, se copiamo oggetti mutabili come elenchi e dizionari.
Python crea copie reali solo se deve, cioè, se l’utente, il programmatore, lo richiede esplicitamente.
Ti presenteremo i problemi più cruciali, che possono verificarsi quando si copiano oggetti mutabili, ad es. quando si copiano elenchi e dizionari.
Copia di una lista
>>> colours1 = >>> colours2 = colours1>>> colours2 = >>> print colours1
Nell’esempio precedente viene assegnata una semplice lista a colori1. Nella fase successiva assegniamo colour1 a colours2. Dopo questo, un nuovo elenco viene assegnato a colori2.
Come ci aspettavamo, i valori dei colori1 sono rimasti invariati., Come nel nostro esempio nel capitolo “Tipi di dati e variabili”, è stata allocata una nuova posizione di memoria per i colori2, perché abbiamo assegnato una nuova lista completa a questa variabile.
>>> colours1 = >>> colours2 = colours1>>> colours2 = "blue">>> colours1
Ma la domanda è, cosa succederà, se cambiamo un elemento della lista di colori2 o colori1?
Nell’esempio sopra, assegniamo un nuovo valore al secondo elemento di colours2. Molti principianti saranno stupiti dal fatto che anche l’elenco dei colori1 sia stato modificato “automaticamente”.,
La spiegazione è che non c’è stata una nuova assegnazione ai colori2, solo a uno dei suoi elementi.
Copia con l’operatore Slice
È possibile copiare completamente le strutture di liste poco profonde con l’operatore slice senza avere nessuno degli effetti collaterali, che abbiamo descritto sopra:
>>> list1 = >>> list2 = list1>>> list2 = 'x'>>> print list2>>> print list1>>>
Ma non appena una lista contiene sottoliste, abbiamo la stessa difficoltà, cioè solo puntatori ai publisher.,
>>> lst1 = ]>>> lst2 = lst1
Questo comportamento è descritto nel seguente diagramma:
Se si assegna un nuovo valore allo 0 ° Elemento di una delle due liste, non ci sarà alcun effetto collaterale. I problemi sorgono se si modifica uno degli elementi della sottolista.
>>> lst1 = ]>>> lst2 = lst1>>> lst2 = 'c'>>> lst2 = 'd'>>> print(lst1)]
Il seguente diagramma descrive cosa succede, se uno degli elementi di una sottolista verrà modificato: sia il contenuto di lst1 che di lst2 vengono modificati.,
Utilizzando il Metodo deepcopy dal modulo copy
Una soluzione ai problemi descritti è usare il modulo “copy”. Questo modulo fornisce il metodo “copia”, che consente una copia completa diuna lista arbitraria, cioè liste superficiali e di altro tipo.
Il seguente script utilizza il nostro esempio sopra e questo metodo:
from copy import deepcopylst1 = ]lst2 = deepcopy(lst1)lst2 = "d"lst2 = "c";print lst2print lst1
Se salviamo questo script sotto il nome di deep_copy.py e se chiamiamo lo script con ” python deep_copy.,py”, riceveremo il seguente output:
$ python deep_copy.py ]]
Capitolo successivo: Funzioni