1

I am struggling with python dictionary. I have two dics named defaultSettings and personalSettings. I want to make function sets personalSettings's values to defaultSettings's values. But I don't want to all changes be applied to defaulSettings.

I tried this code:

defaultSettings = {'s1': 1, 's2':2, 's3':3}

personalSettings = {'s1': 3, 's2':2, 's3':1}

print(defaultSettings)
print(personalSettings)
print('-*-*-*-*-*-*-*-*-*-*-*-*')

personalSettings = defaultSettings

print(defaultSettings)
print(personalSettings)
print('-*-*-*-*-*-*-*-*-*-*-*-*')

personalSettings['s1'] = 5

print(defaultSettings)
print(personalSettings)

And my output is:

{'s1': 1, 's2': 2, 's3': 3}
{'s1': 3, 's2': 2, 's3': 1}
-*-*-*-*-*-*-*-*-*-*-*-*
{'s1': 1, 's2': 2, 's3': 3}
{'s1': 1, 's2': 2, 's3': 3}
-*-*-*-*-*-*-*-*-*-*-*-*
{'s1': 5, 's2': 2, 's3': 3}
{'s1': 5, 's2': 2, 's3': 3}
-*-*-*-*-*-*-*-*-*-*-*-*

If I change a value of personalSettings after personalSettings = defaultSettings, defaultSettings's value changes too. I know this;

enter image description here

But I don't know how avoid this or other way.

Seminet
  • 69
  • 6
  • 1
    You are currently making `personalSettings` another name for `defaultSettings`. Do you want to make `personalSettings` refer to a copy of `defaultSettings`, or do you want to update `personalSettings` in place, replacing the current contents with the contents of `defaultSettings`? (If you don't understand the distinction, see https://nedbatchelder.com/text/names.html.) – chepner Sep 27 '22 at 20:28
  • 1
    @chepner is correct, you should call `.copy()` if you want an actual `copy` instead of a `reference`. – arckoor Sep 27 '22 at 20:29
  • You can also use `personalSettings.update(defaultSettings)` to merge them. – Barmar Sep 27 '22 at 20:30
  • @chepner I want to update `personalSettings` in place, replacing the current contents with the contents of `defaultSettings`. I understand the distinction if I don't, probably I were thinking "Where is the error?! It should be work!" – Seminet Sep 27 '22 at 20:31
  • @Barmar No, I don't want to merge them. – Seminet Sep 27 '22 at 20:32

2 Answers2

3

Consider

>>> defaults = {'foo': 'bar', 'bee': 'blah'}
>>> actual = dict(defaults)
>>> actual['foo'] = 'BAZ'
>>> defaults
{'foo': 'bar', 'bee': 'blah'}
>>> actual
{'foo': 'BAZ', 'bee': 'blah'}

The trick is actual = dict(defaults). This way actual can be changed without affecting defaults.

If your dicts have sub-objects, consider deepcopy or json.dumps/loads to make a deep copy:

>>> myDict = {'s1':1,  's2':{'b1':2, 'b2':3}}
>>>
>>> from copy import deepcopy
>>>
>>> myDict2 = deepcopy(myDict)
>>>
>>> myDict2['s2']['b1'] = 99
>>>
>>> myDict
{'s1': 1, 's2': {'b1': 2, 'b2': 3}}
>>> myDict2
{'s1': 1, 's2': {'b1': 99, 'b2': 3}}
gog
  • 10,367
  • 2
  • 24
  • 38
1

I would use defaultSettings.copy() or dict(defaultSettings) to create a copy of the dict

David Tejuosho
  • 177
  • 1
  • 14