Reputation: 23
Somehow my two identical nested dictionaries (a dictionary containing dictionaries), created through different means, act differently when I try to assign a new value to a key.
d = {'a': {'item': None},'b': {'item': None},'c': {'item': None}}
The first dictionary is created manually, while the second one is created through this code:
data = {"item" : None}
keys = ["a","b","c"]
d2 = dict()
for i in range(len(keys)):
d2[keys[i]] = data
Both of these give seemingly identical dictionaries.
print d
{'a': {'item': None}, 'c': {'item': None}, 'b': {'item': None}}
print d2
{'a': {'item': None}, 'c': {'item': None}, 'b': {'item': None}}
Everything seems good so far, but when I try to change the value of any of the keys, this happens:
d["a"]["item"] = "1"
d2["a"]["item"] = "1"
print d
{'a': {'item': '1'}, 'c': {'item': None}, 'b': {'item': None}}
print d2
{'a': {'item': '1'}, 'c': {'item': '1'}, 'b': {'item': '1'}}
I've tried everything I can think of and I can't find anyone that has had a similar problem. It just doesn't makes sense, why would it change the value in all three of the inside dictionaries? I hope you guys can help.
I'm using Python 2.7.5
Upvotes: 2
Views: 29
Reputation: 13806
When you assign dict2 = dict1
, you are not making a copy of dict1
, it results in dict2
being just another name for dict1
.
You can do this using deepcopy
:
data = {"item" : None}
keys = ["a","b","c"]
d2 = dict()
for i in range(len(keys)):
d2[keys[i]] = copy.deepcopy(data)
But if you have data like :
data = {"item1" : None, "item2":{"Book":none}}
another dictionary
inside your data dictionary
, you must have to use deepcopy
like above.
Otherwise, there are different way to copy your dict
. Like
d2[keys[i]] = copy.copy(data)
d2[keys[i]] = dict(data)
d2[keys[i]] = data.copy()
You can use any to copy your dict
. Just use deepcopy
when you have nested dict
Upvotes: 1
Reputation: 26129
You need to create a unique dict for each entry, like so:
keys = ["a","b","c"]
d2 = dict()
for i in range(len(keys)):
d2[keys[i]] = {"item" : None}
Also you might prefer a more pythonic way:
>>> {k:{'item':None} for k in ['a','b','c']}
{'a': {'item': None}, 'c': {'item': None}, 'b': {'item': None}}
Upvotes: 4