How to Copy a Dictionary in Python
- Copy a Dictionary in Python: Passing by Reference
- Copy a Dictionary in Python: Passing by Value
- Shallow Copy of Python Dictionary
This tutorial discusses how you can copy a dictionary in Python.
We’re going to demonstrate how to copy a dictionary in two ways: passing by value and passing by reference.
Copy a Dictionary in Python: Passing by Reference
In Python, objects are not implicitly copied. If we try and copy food
to a new variable meal
, the values of food
will be copied into meal
, but so will the reference of food
.
meal = food
Directly equating one object to another will make the new object point to the previous one; this means that the two variables will reference the same unique object.
If we update the value Fruit
in meal
to Banana
, the value of Fruit
in food
will also be replaced.
meal["Fruit"] = "Banana"
print(food)
print(meal)
Output:
{'Fruit': 'Banana', 'Vegetable': 'Lettuce', 'Poultry': 'Chicken', 'Fish': 'Cod'}
{'Fruit': 'Banana', 'Vegetable': 'Lettuce', 'Poultry': 'Chicken', 'Fish': 'Cod'}
The same goes if we try and update a key in the meal
block. We’ll replace the key Fruit
with Circle Fruit
and copy its value before popping it out of the dictionary.
meal["Circle Fruit"] = meal.pop("Fruit")
print(food)
print(meal)
Output:
{'Vegetable': 'Lettuce', 'Poultry': 'Chicken', 'Fish': 'Cod', 'Circle Fruit': 'Orange'}
{'Vegetable': 'Lettuce', 'Poultry': 'Chicken', 'Fish': 'Cod', 'Circle Fruit': 'Orange'}
The value of food
still will be replaced even if we didn’t directly modify it; this is because the method we used to copy food
to meal
is passing by reference.
Copy a Dictionary in Python: Passing by Value
Passing by value means that an actual copy of the object will be created in memory, instead of pointing the copy to the original object upon copying an object.
If we want to copy a dictionary and avoid referencing the original values, then we should find a way to instantiate a new object in the memory. In Python, there are a few functions that support this approach: dict()
, copy()
, and deepcopy()
.
The dict()
function instantiates a new dictionary object. If you wrap an existing dictionary around this function, a new instance of the object would be created.
For this method, we’re going to use the same example from the dictionary food
.
meal = dict(food)
Another way to pass by value is by using the copy()
command, which does the same thing that dict()
does: instantiating a new object in the memory. The difference is that copy()
is a built-in function of collection objects, including dictionaries.
meal = food.copy()
For both scenarios, let’s modify the Fruit
value and replace the Vegetable
key:
meal["Fruit"] = "Apple"
meal["Greens"] = meal.pop("Vegetable")
print(food)
print(meal)
Output:
{'Fruit': 'Orange', 'Vegetable': 'Lettuce', 'Poultry': 'Chicken', 'Fish': 'Cod'} # food (original)
{'Fruit': 'Apple', 'Poultry': 'Chicken', 'Fish': 'Cod', 'Greens': 'Lettuce'} # meal (copy)
By instantiating a new object meal
using dict()
or copy()
, we avoid referencing the original object and updating its values if meal
is updated.
Shallow Copy of Python Dictionary
The problem with dict()
and copy()
is they only apply shallow copy to the object being used; this will be a problem if your dictionary has a complex nested structure.
Shallow copying will only copy the first layer in the memory that it sees because nested objects take up new spaces.
Let’s change the original object to a nested dictionary.
info = {
"Numbers": [1, 2, 3],
"Resident Name": "Sherlock",
"Address": {"Street": "Baker", "Number": "221B", "City": "Miami"},
}
Let’s declare a new object info2
using copy()
and dict()
to copy from info
and change some values in the nested dictionary.
info2 = info.copy() # or dict(info)
info2["Numbers"][1] = 4
info2["Resident Name"] = "Holmes"
info2["Address"]["City"] = "Lexington"
print(info)
print(info2)
Output:
{'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'}}
The new values of Numbers
and Address.City
are updated in both the original and copy versions. The Resident Name
value only updated the info2
block because we only performed a shallow copy on the object.
Deep Copy With copy
Module in Python
Deep copy essentially fixes the problem of shallow copying. Upon copying an object, it checks for nested objects and recursively creates new objects in the memory.
In Python, we can achieve deep copying with the module copy
, which contains shallow and deep copy operations and utilities.
import copy
We will use the deepcopy()
function of the module to deep copy the nested objects within our dictionary. We’ll use the same example info
block above.
info2 = copy.deepcopy(info)
info2["Numbers"][1] = 4
info2["Resident Name"] = "Holmes"
info2["Address"]["City"] = "Lexington"
print(info)
print(info2)
Output:
{'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'}}
Now, the original dictionary info
remains unchanged, even with the multiple changes in info2
, including the nested objects.
In summary, there are many ways for you to copy a dictionary in Python, but the output won’t be the same for all. Directly assigning a dictionary with =
will pass it by reference, pointing to the original object.
Shallow copying functions like dict()
and copy()
will solve that problem only for non-nested dictionaries.
The best way to copy a dictionary, considering nested dictionaries, is to use the deepcopy()
function provided by the copy
module.
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