
Table of Contents(目次)
Behavior When Referencing the Same dict Object in Python
Like lists and tuples, dicts are managed by being referenced from variables. Therefore, if you copy with something like d2 = d1
, both variables will reference the same object, so changing an element will affect the other as well.
d1 = {'key1': 1, 'key2': 2}
d2 = d1
d2['key2'] = 10
d2['key3'] = 30
print('d1', d1, id(d1)) # d1 {'key1': 1, 'key2': 10, 'key3': 30} 2827504193216
print('d2', d2, id(d2)) # d2 {'key1': 1, 'key2': 10, 'key3': 30} 2827504193216
How to Duplicate a Python dict with a Shallow Copy
Since dicts do not support slicing like lists or tuples, use the copy()
method. This performs a shallow copy, so nested lists or dicts are not duplicated.
If the dict is not nested or you are sure you will not modify nested parts, the copy()
method is sufficient.
d1 = {'key1': 1, 'key2': 2}
d2 = d1.copy()
d2['key2'] = 10
d2['key3'] = 30
print('d1', d1, id(d1)) # d1 {'key1': 1, 'key2': 2} 3208174636736
print('d2', d2, id(d2)) # d2 {'key1': 1, 'key2': 10, 'key3': 30} 3208174647808
Cautions When Shallow Copying Nested dicts in Python
Let’s check the behavior when the data is nested, as in the following code.
d1 = {'profile': {'age': 10}, 'friends': ['Emma']}
d2 = d1.copy()
d2['profile']['age'] = 99
d2['friends'].append('NICOLAS')
print('d1', d1, id(d1)) # d1 {'profile': {'age': 99}, 'friends': ['Emma', 'NICOLAS']} 2464997588928
print('d2', d2, id(d2)) # d2 {'profile': {'age': 99}, 'friends': ['Emma', 'NICOLAS']} 2464997588864
print('d1["profile"]', d1['profile'], id(d1['profile'])) # d1["profile"] {'age': 99} 2464997576448
print('d2["profile"]', d2['profile'], id(d2['profile'])) # d2["profile"] {'age': 99} 2464997576448
print('d1["friends"]', d1['friends'], id(d1['friends'])) # d1["friends"] ['Emma', 'NICOLAS'] 2464997554752
print('d2["friends"]', d2['friends'], id(d2['friends'])) # d2["friends"] ['Emma', 'NICOLAS'] 2464997554752
The “outer” dict is duplicated by the copy()
method, resulting in a different id. However, the dicts and lists assigned as value still reference the same objects, so editing them will affect both.
(※ However, if you never modify the elements of the nested objects, a shallow copy is sufficient.)
How to Deep Copy Nested dicts in Python and Differences from Shallow Copy
Next, let’s see the execution result of performing a deep copy. Use the copy module’s deepcopy()
function.
import copy
d1 = {'profile': {'age': 10}, 'friends': ['Emma']}
d2 = copy.deepcopy(d1)
d2['profile']['age'] = 99
d2['friends'].append('NICOLAS')
print('d1', d1, id(d1)) # d1 {'profile': {'age': 10}, 'friends': ['Emma']} 1303331618752
print('d2', d2, id(d2)) # d2 {'profile': {'age': 99}, 'friends': ['Emma', 'NICOLAS']} 1303331618432
print('d1["profile"]', d1['profile'], id(d1['profile'])) # d1["profile"] {'age': 10} 1303331606336
print('d2["profile"]', d2['profile'], id(d2['profile'])) # d2["profile"] {'age': 99} 1303331618560
print('d1["friends"]', d1['friends'], id(d1['friends'])) # d1["friends"] ['Emma'] 1303331584640
print('d2["friends"]', d2['friends'], id(d2['friends'])) # d2["friends"] ['Emma', 'NICOLAS'] 1303331482048
You can confirm that all ids, including those of nested dicts and lists, are different. This ensures that editing nested objects no longer affects the other copy.
(※ However, fully duplicating everything may impact memory usage and processing speed. Choose between shallow and deep copies depending on your processing needs.)