简体   繁体   中英

Python dictionary update to a list gives wrong output

My problem is when updating a dictonary to a list.

Input:

>>> res=[]
>>> my_inital_dict={'aa':1,'bb':1}
>>> for i in range(4):
...     my_initial_dict.update({'aa':i+4})
...     print my_initial_dict
...     res.append(my_initial_dict)

Output I got:

{'aa': 4, 'bb': 1}
{'aa': 5, 'bb': 1}
{'aa': 6, 'bb': 1}
{'aa': 7, 'bb': 1}
>>> res
[{'aa': 7, 'bb': 1}, {'aa': 7, 'bb': 1}, {'aa': 7, 'bb': 1}, {'aa': 7, 'bb': 1}]

When I print my_initial_dict within the loop, I'm getting correct values. But when I print the resulting list, I'm getting list of dictonary with same dict repeated 4 times. Can someone explain what is happening here?

All items in your res list are referencing the same object , as said before.

You: Append this mutable object to a list, change it, and append it again, now show me what that looks like.

Computer: Add object to list, add same object to list, here is your list, it has the same two objects in it.

Here is another way to say that; First you build the list with the objects, and then your display the list of objects, which in this case is a list of the same object , so it displays the latest state of that object in each position of the list, not the state at which you added it, unless you make a copy of it.

Other ways to do it, just for fun;

Nested Comprehension or map with lamda, with copy() and update()

my_inital_dict={'aa':1,'bb':1}
res = [x[1] for x in [(my_inital_dict.update({'aa':i+4}),
       my_inital_dict.copy()) for i in range(4)]]

-or-

res = map(lambda i: my_inital_dict.update({'aa':i+4}) or my_inital_dict.copy(),
      range(4))

You're appending the dictionary to res in the loop every time, that's why you are seeing the repeat. They all have the same values because you are updating the same dict everytime

res=[]
my_inital_dict={'aa':1,'bb':1}
updates = [my_initial_dict]
for i in range(4):
   updates.append({'aa':i+4})
   my_initial_dict.update({'aa':i+4})
   res = my_initial_dict
print updates

All list items are reference the same dictionary object. Make a copy:

res = []
my_initial_dict = {'aa':1,'bb':1}
for i in range(4):
    d = my_initial_dict.copy()
    d['aa'] = i + 4
    print d
    res.append(d)
print res

You are updating same dict every time in for loop. As python uses 'call by reference' structure, you are every time pointing to same object and making changes in same and appending same dict to list ie you are appending same object.

this can be called as a soft copy of object. If you want to have all updated dicts in list, you have to go for deep copy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM