Reputation: 169
>>> docsite = {'text1':1, 'text2':1}
>>> doc = {
'field1': docsite,
'field2': docsite
}
>>> doc['field2']['text1'] += 2
after this when i print doc variable, i get
>>> doc
{'field2': {'text2': 1, 'text1': 3}, 'field1': {'text2': 1, 'text1': 3}}
I change value in field2 only. Somehow, values in field1 is also getting updated.
Question:
Why?
How to resolve it?
Upvotes: 0
Views: 372
Reputation: 22071
Dict's are mutable objects in python. When you assign dict
to other variable it's assigned by reference, what leads to problem you have described.
So in your case both values of keys in doc
dict (field1,field2) point to same variable (docsite
). That's way you have such behaviour.
To fix that use dict copy method before assigning it to doc
keys.
docsite = {'text1':1, "text2":1}
doc = {
"field1": docsite.copy(),
"field2": docsite.copy()
}
There are two types of copies in python, deepcopy and shallow copy ( see that SO answer to understand difference between them).
The example above is just shallow copy of docsite
. However you can make deepcopy by using code below:
import copy
docsite = {'text1':1, "text2":1}
doc = {
"field1": copy.deepcopy(docsite),
"field2": copy.deepcopy(docsite)
}
See Immutable vs Mutable types that's good SO question to discover that topic for python...
Upvotes: 3
Reputation: 3235
In your second dictionary you save the pointer to docsite. So, when you change it, it will change for all.
To solve it you have to copy.
doc = {
"field1":docsite.copy(),
"field2":docsite.copy(),
}
I'm not sure about copy function, if it doesn't work just try to google "python clone dictionary"
Upvotes: 1
Reputation: 11097
Python does not work with copy of object, when assigning your fields to docsite
, both satellite values are pointing towards the same object. You can check using id()
method: id(doc['field2']) == doc['field1']
. Use deepcopy
if you need different copy of your initial object.
import copy
doc['field2'] = copy.deepcopy(docsite)
Update: Of course, this will require to import the copy
module in order to use it (as underlined by Andriy Ivaneyko
).
Upvotes: 2
Reputation: 2832
Your docsite
variable is a reference to a dictionnary, therefore, storing it at different locations (e.g. associated to different keys in another dictionary) will make them share the same dictionary in memory.
To resolve this, you may want to do a copy
of your dictionary:
doc = {'field1': docsite, 'field2': docsite.copy()}
Note that, if in docsite
you have references to other objects (list
, other dict
, etc) then you may have to use a deepcopy
:
import copy
d2 = copy.deepcopy(docsite)
Upvotes: 3
Reputation: 369454
Because the values in the doc
dictionary refers the same dictionary object.
To solve, pass copies of the dictionaries, so that values refers different dictionary objects:
doc = {
"field1": dict(docsite), # or docsite.copy()
"field2": dict(docsite), # or docsite.copy()
}
Upvotes: 2
Reputation: 2444
import copy
doc = {
"field1":docsite,
"field2":copy.deepcopy(docsite)
}
Both keys in doc map to the same object, when you change the value of one key you are changing the docsite object, same object the other key also map to.
Upvotes: 2