0

I am changing value in the dictionary on the list by index. But all the similar dictionaries in the list also update this key's value. My code is.

 list=[]
 dict = {'id':2,'name':'hanna', 'age':30}
 list.append(dict)
 list.append(dict)
 list.append(dict) 
 list.append(dict)
 list.append(dict)
 list

Result

[{'age': 30, 'id': 2, 'name': 'hanna'},
 {'age': 30, 'id': 2, 'name': 'hanna'},
 {'age': 30, 'id': 2, 'name': 'hanna'},
 {'age': 30, 'id': 2, 'name': 'hanna'},
 {'age': 30, 'id': 2, 'name': 'hanna'}]

I want to change only this one

 list[0]['age']='99'

but this update all the dictionaries in the list also..

[{'age': '99', 'id': 2, 'name': 'hanna'},
 {'age': '99', 'id': 2, 'name': 'hanna'},
 {'age': '99', 'id': 2, 'name': 'hanna'},
 {'age': '99', 'id': 2, 'name': 'hanna'},
 {'age': '99', 'id': 2, 'name': 'hanna'}]

I need this

[{'age': 99, 'id': 2, 'name': 'hanna'},
 {'age': 30, 'id': 2, 'name': 'hanna'},
 {'age': 30, 'id': 2, 'name': 'hanna'},
 {'age': 30, 'id': 2, 'name': 'hanna'},
 {'age': 30, 'id': 2, 'name': 'hanna'}]

Why? And how change the value in the dict by index?

Andrey
  • 21
  • 3
  • This is because of the mutable property of some objects in python. You can read here to understand it https://medium.com/@meghamohan/mutable-and-immutable-side-of-python-c2145cf72747 – nacho May 15 '19 at 14:44
  • Wow! Thank you! This resolve my issue ! ` list.append(dict.copy())` – Andrey May 15 '19 at 14:45
  • Thank you @nacho interesting! – Andrey May 15 '19 at 15:17

2 Answers2

1

Even though this will be closed, I can understand that for a beginner the linked duplicate can be really confusing.

I just wanted to add a simpler explanation in the hope of helping you.

Basically, when you append to your list, it is the same object everytime.

Here is the proof,

list=[]
dict = {'id':2,'name':'hanna', 'age':30}
list.append(dict)
list.append(dict)
print(id(list[0]))
print(id(list[1]))

Example of output:

>>> 11301752
    11301752

So, when you're mutating the value after, you're actually doing it on the same object reference.

If you want more explanations on to how to overcome your problem definitely follow the duplicate link, it has a lot more information for you.

scharette
  • 9,437
  • 8
  • 33
  • 67
0

Python passes arguments "by object", which means that what the called function gets is not a copy but the original object itself - IOW, your list contains n references to the very same dict instance, so however you access it (via the name dict or via list[n]), it's still the very same dict you're updating. Note that this works the same for bindings, ie foo = {}; bar = foo will not create a copy of foo but make both names point to the same dict. All this is very clearly explained here

The cure is very obvious: make copies of the dict:

mydict = {"a":1}
mylist = []
mylist.append(mydict.copy())
mylist.append(mydict.copy())
mylist[1]["a"] = 42
print(mylist)
print(mydict)

Also note that dict.copy() returns a shallow copy. If your dict contains lists, other dicts or any mutable object, you may want a deepcopy instead.

bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
  • Thank you @bruno desthuilliers! You know it is realy hard to search the answer for this problem from the novice point of view. Thanks again! – Andrey May 15 '19 at 14:57