I am trying to update the values in the internal dictonary but it is updating in the both, I tried a lot but still facing the same problem. Thanks in advance.
arr = [1,2]
d_int = {'a':False, 'e':False, 'i':False, 'o':False, 'u':False}
d_main ={i : d_int for i in range(len(arr))}
print(d_main)
d_main[0]['a'] = True
d_main[1]['i'] = True
print(d_main)
Result:
{0: {'a': True, 'e': False, 'i': True,
'o': False, 'u': False},
1: {'a': True, 'e': False, 'i': True,
'o': False, 'u': False}
}
Need something like this:
{0: {'a': True, 'e': False, 'i': False,
'o': False, 'u': False},
1: {'a': False, 'e': False, 'i': True,
'o': False, 'u': False}
}
This is because all values of the d_main
refer to the same dict object d_int
. Changes to any one of them will reflect across all references. Further read
To avoid the issue, ensure you create a new copy of the dict object during your list comprehension, using copying methods such as .copy
.
arr = [1,2]
d_int = {'a':False, 'e':False, 'i':False, 'o':False, 'u':False}
d_main ={i : d_int.copy() for i in range(len(arr))} #modified.
print(d_main)
d_main[0]['a'] = True
d_main[1]['i'] = True
print(d_main)
#Output:
{0: {'a': True, 'e': False, 'i': False, 'o': False, 'u': False}, 1: {'a': False, 'e': False, 'i': True, 'o': False, 'u': False}}
Short workaround: Change d_int to d_int.copy() and you'll have your output. You are referencing the same object. Look at the difference in the id in these two cases:
arr = [1,2]
d_int = {'a':False, 'e':False, 'i':False, 'o':False, 'u':False}
d_main ={i : d_int for i in range(len(arr))}
print(list(map(id,d_main.values())))
Returns:
[140545244867248, 140545244867248] # <-- they are the same
arr = [1,2]
d_int = {'a':False, 'e':False, 'i':False, 'o':False, 'u':False}
d_main ={i : d_int.copy() for i in range(len(arr))} # <-- .copy() added
print(list(map(id,d_main.values())))
Returns:
[140545244796464, 140545244798480]
If you are new without any programming experience in any programming language, For understanding why the problem happen, you'd better to know what is pointer in C programming language firstly.
copy.deepcopy
is the best. dict.copy
have same trouble in deep nested dict. as follows.
a = {"1": {"2": 2, "3": 3}, "4":4}
c = {1:a.copy()}
b = {1:a.copy()}
c[1]['1']['2'] = 5
c[1]['4'] = 40
print(c)
# {1: {'1': {'3': 3, '2': 5}, '4': 40}}
print(b)
# {1: {'1': {'3': 3, '2': 5}, '4': 4}}
But copy.deepcopy
is work well with deep nested dict.
from copy import deepcopy
a = {"1": {"2": 2, "3": 3}, "4":4}
c = {1: deepcopy(a)}
b = {1: deepcopy(a)}
c[1]['1']['2'] = 5
c[1]['4'] = 40
print(c)
# {1: {'1': {'2': 5, '3': 3}, '4': 40}}
print(b)
# {1: {'1': {'2': 2, '3': 3}, '4': 4}}
Actually, this problem is not only happen to nested dict, other types as well, likes nested list, class with dict property and so on, and copy.deepcopy
is work well.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.