Copia un dizionario in Python
- Copia un dizionario in Python: passaggio per riferimento
- Copia un dizionario in Python: passaggio per valore
- Copia superficiale del dizionario Python
Questo tutorial spiega come copiare un dizionario in Python.
Dimostreremo come copiare un dizionario in due modi: passando per valore e passando per riferimento.
Copia un dizionario in Python: passaggio per riferimento
In Python, gli oggetti non vengono copiati implicitamente. Se proviamo a copiare food
in una nuova variabile meal
, i valori di food
verranno copiati in meal
, ma lo sarà anche il riferimento di food
.
meal = food
L’equazione diretta di un oggetto con un altro farà sì che il nuovo oggetto punti a quello precedente; ciò significa che le due variabili faranno riferimento allo stesso oggetto univoco.
Se aggiorniamo il valore Fruit
in meal
in Banana
, anche il valore di Fruit
in food
verrà sostituito.
meal["Fruit"] = "Banana"
print(food)
print(meal)
Produzione:
{'Fruit': 'Banana', 'Vegetable': 'Lettuce', 'Poultry': 'Chicken', 'Fish': 'Cod'}
{'Fruit': 'Banana', 'Vegetable': 'Lettuce', 'Poultry': 'Chicken', 'Fish': 'Cod'}
Lo stesso vale se proviamo ad aggiornare una chiave nel blocco meal
. Sostituiremo la chiave Fruit
con Circle Fruit
e copieremo il suo valore prima di estrarlo dal dizionario.
meal["Circle Fruit"] = meal.pop("Fruit")
print(food)
print(meal)
Produzione:
{'Vegetable': 'Lettuce', 'Poultry': 'Chicken', 'Fish': 'Cod', 'Circle Fruit': 'Orange'}
{'Vegetable': 'Lettuce', 'Poultry': 'Chicken', 'Fish': 'Cod', 'Circle Fruit': 'Orange'}
Il valore di food
verrà comunque sostituito anche se non lo abbiamo modificato direttamente; questo perché il metodo che abbiamo usato per copiare food
in meal
passa per riferimento.
Copia un dizionario in Python: passaggio per valore
Passare per valore significa che una copia effettiva dell’oggetto verrà creata in memoria, invece di puntare la copia all’oggetto originale quando si copia un oggetto.
Se vogliamo copiare un dizionario ed evitare di fare riferimento ai valori originali, allora dovremmo trovare un modo per istanziare un nuovo oggetto nella memoria. In Python, ci sono alcune funzioni che supportano questo approccio: dict()
, copy()
e deepcopy()
.
La funzione dict()
istanzia un nuovo oggetto dizionario. Se avvolgi un dizionario esistente attorno a questa funzione, verrà creata una nuova istanza dell’oggetto.
Per questo metodo, utilizzeremo lo stesso esempio dal dizionario food
.
meal = dict(food)
Un altro modo per passare per valore è usare il comando copy()
, che fa la stessa cosa di dict()
: istanziare un nuovo oggetto nella memoria. La differenza è che copy()
è una funzione incorporata degli oggetti di raccolta, inclusi i dizionari.
meal = food.copy()
Per entrambi gli scenari, modifichiamo il valore Fruit
e sostituiamo la chiave Vegetable
:
meal["Fruit"] = "Apple"
meal["Greens"] = meal.pop("Vegetable")
print(food)
print(meal)
Produzione:
{'Fruit': 'Orange', 'Vegetable': 'Lettuce', 'Poultry': 'Chicken', 'Fish': 'Cod'} # food (original)
{'Fruit': 'Apple', 'Poultry': 'Chicken', 'Fish': 'Cod', 'Greens': 'Lettuce'} # meal (copy)
Istanziando un nuovo oggetto meal
usando dict()
o copy()
, evitiamo di fare riferimento all’oggetto originale e di aggiornare i suoi valori se meal
viene aggiornato.
Copia superficiale del dizionario Python
Il problema con dict()
e copy()
è che applicano solo una copia superficiale all’oggetto in uso; questo sarà un problema se il tuo dizionario ha una complessa struttura nidificata.
La copia superficiale copierà solo il primo livello nella memoria che vede perché gli oggetti annidati occupano nuovi spazi.
Cambiamo l’oggetto originale in un dizionario annidato.
info = {
"Numbers": [1, 2, 3],
"Resident Name": "Sherlock",
"Address": {"Street": "Baker", "Number": "221B", "City": "Miami"},
}
Dichiariamo un nuovo oggetto info2
usando copy()
e dict()
per copiare da info
e cambiamo alcuni valori nel dizionario annidato.
info2 = info.copy() # or dict(info)
info2["Numbers"][1] = 4
info2["Resident Name"] = "Holmes"
info2["Address"]["City"] = "Lexington"
print(info)
print(info2)
Produzione:
{'Numbers': [1, 4, 3], 'Resident Name': 'Sherlock', 'Address': {'Street': 'Baker', 'Number': '221B', 'City': 'Lexington'}}
{'Numbers': [1, 4, 3], 'Resident Name': 'Holmes', 'Address': {'Street': 'Baker', 'Number': '221B', 'City': 'Lexington'}}
I nuovi valori di Numbers
e Address.City
vengono aggiornati sia nella versione originale che in quella di copia. Il valore Resident Name
ha aggiornato solo il blocco info2
perché abbiamo eseguito solo una copia superficiale sull’oggetto.
Copia profonda con il modulo copy
in Python
La copia profonda risolve essenzialmente il problema della copia superficiale. Dopo aver copiato un oggetto, verifica la presenza di oggetti nidificati e crea in modo ricorsivo nuovi oggetti nella memoria.
In Python, possiamo ottenere una copia profonda con il modulo copy
, che contiene operazioni e utilità di copia superficiale e profonda.
import copy
Useremo la funzione deepcopy()
del modulo per copiare in profondità gli oggetti annidati all’interno del nostro dizionario. Useremo lo stesso blocco info
di esempio sopra.
info2 = copy.deepcopy(info)
info2["Numbers"][1] = 4
info2["Resident Name"] = "Holmes"
info2["Address"]["City"] = "Lexington"
print(info)
print(info2)
Produzione:
{'Numbers': [1, 2, 3], 'Resident Name': 'Sherlock', 'Address': {'Street': 'Baker', 'Number': '221B', 'City': 'Miami'}}
{'Numbers': [1, 4, 3], 'Resident Name': 'Holmes', 'Address': {'Street': 'Baker', 'Number': '221B', 'City': 'Lexington'}}
Ora, il dizionario originale info
rimane invariato, anche con le molteplici modifiche in info2
, inclusi gli oggetti annidati.
In sintesi, ci sono molti modi per copiare un dizionario in Python, ma l’output non sarà lo stesso per tutti. Assegnare direttamente un dizionario con =
lo passerà per riferimento, puntando all’oggetto originale.
Funzioni di copia superficiale come dict()
e copy()
risolveranno il problema solo per dizionari non annidati.
Il modo migliore per copiare un dizionario, considerando i dizionari annidati, è usare la funzione deepcopy()
fornita dal modulo copy
.
Skilled in Python, Java, Spring Boot, AngularJS, and Agile Methodologies. Strong engineering professional with a passion for development and always seeking opportunities for personal and career growth. A Technical Writer writing about comprehensive how-to articles, environment set-ups, and technical walkthroughs. Specializes in writing Python, Java, Spring, and SQL articles.
LinkedIn