sec02 - dict Copying
Eyecatch Data Structures
スポンサーリンク

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.)

スポンサーリンク