(not sure how to best word the question title)
I have a situation similar to the following:
In [1]: t = {1:2}
In [2]: x = {'a' : t, 'b' : t}
In [3]: x
Out[3]: {'a': {1: 2}, 'b': {1: 2}}
In [4]: x['a'].update({1:4})
In [5]: x
Out[5]: {'a': {1: 4}, 'b': {1: 4}}
In [6]:
But the dictionary is more complex.
I would like to ensure that no elements of the dictionary are references to any other elements in the dictionary, so that I'm able to update sub-sections of it without affecting others.
Ideally I would like to have something similar to:
t = {1:2}
x = {'a' : t, 'b' : t}
x = f(x)
x['a'].update({1:4})
# x is now: {'a': {1: 4}, 'b': {1: 2}}
Edit - additional information
Previous test case wasn't deep enough.
def get_dict():
d1 = {
1.0: "something",
2.0: "other",
}
d2 = {"z": d1}
tst = {
"main_key": {
"x": d2,
"y": d2,
}
}
return tst
Using this function I have:
from copy import deepcopy
tst = get_dict()
tst = deepcopy(tst)
tst["main_key"]["x"].update({1: "check"})
Which outputs:
{'main_key': {'x': {1: 'check', 'z': {1.0: 'something', 2.0: 'other'}},
'y': {1: 'check', 'z': {1.0: 'something', 2.0: 'other'}}}}
Rather than the expected:
{'main_key': {'x': {1: 'check', 'z': {1.0: 'something', 2.0: 'other'}},
'y': {1: 'something', 'z': {1.0: 'something', 2.0: 'other'}}}}
CodePudding user response:
To simplify, when you do b = deepcopy(a)
, that means that nested dictionaries in b
are not identical to the nested dictionaries in a
, but it doesn't break the internal structure. Dictionaries accessible via different keys are still identical, and cyclical dictionaries (for example a[some_key] is a
) remain cyclical.
The best way to deal with this is to make sure your dictionary doesn't have any unwanted shared references in the first place, for example by doing:
return {
"main_key": {
"x": d2,
"y": deepcopy(d2),
}
}
But if you don't control the way the data arrives, you could use a recursive function like this one:
def copy_tree(original):
'''Creates a deep copy of a dictionary, but the copy will
be a tree, so no shared references. Cyclic dictionaries will
cause a recursion error.
All keys, and all non-dictionary values are not copied but used
as-is.'''
if isinstance(original, dict):
return {key: copy_tree(value) for key, value in original.items()}
return original
CodePudding user response:
You can use .copy() on t
.
t = {1:2}
x = {'a' : t.copy(), 'b' : t.copy()}
print(x) #{'a': {1: 2}, 'b': {1: 2}}
x['a'].update({1:4})
print(x) #{'a': {1: 4}, 'b': {1: 2}}
CodePudding user response:
You can create a new copy of the dictionary using deepcopy
from copy:
from copy import deepcopy
x = deepcopy(x)
x['a'].update({1: 4})
#x: {'a': {1: 4}, 'b': {1: 4}}
#t: {1: 2}