Reputation: 11028
I had this:
[{'name': 'Peter'}, {'name': 'Anna'}]
And I wanted to make this out of it:
[{'name': 'Peter Williams'}, {'name': 'Anna Williams'}]
So I did:
>>> li = [{'name': 'Peter'}, {'name': 'Anna'}]
>>> new_li = []
>>> dic = {}
>>> for i in li:
... dic["name"] = i["name"] + " Williams"
... new_li.append(dic)
But:
>>> new_li
[{'name': 'Anna Williams'}, {'name': 'Anna Williams'}]
Why?
Could you also show how to best get [{'name': 'Peter Williams'}, {'name': 'Anna Williams'}]
?
Edit
The reason why I didn't understand this behavior is because I assumed that:
>>> dict = {'name':'Peter'}
>>> lis = [dict]
>>> dict['name'] = 'Olaf'
Where
>>> print lis
gives
[{'name': 'Peter'}]
While it actually is
[{'name': 'Olaf'}]
Upvotes: 1
Views: 71
Reputation: 50497
Because you're using the same dictionary object in each iteration.
On the second iteration, you are altering the value that you assigned to the name
key in the previous iteration, and your list ends up containing two references to the same object.
I'd strongly recommend checking out the "Python Tutor" tool (pythontutor.com), which allows you to visualise the execution of some python code, and see what objects are being created in the stack. e.g. Python Tutor with your code
The correct way to do what you wanted would be:
li = [{'name': 'Peter'}, {'name': 'Anna'}]
new_li = []
for p in li:
new_p = {'name': p['name'] + ' Williams'}
new_li.append(new_p)
This way a new dictionary object is created with each iteration.
A more concise solution:
li = [{'name': 'Peter'}, {'name': 'Anna'}]
new_li = [{'name': p['name'] + ' Williams'} for p in li]
Upvotes: 2
Reputation: 2885
You have run into a really nasty problem. The problem is with your dic
. You are iterating over the list of names, and first you hit the one with 'Peter'. At this point, you set dic
to {'name': 'Peter Williams'}
and append it. But then, you hit the one with 'Anna' and change that very same dic
to {'name': 'Anna Williams'}
. So you end up with the same dictionary in your list twice. To fix this, you will need to do this instead:
new_li = []
for i in li:
n_li.append({'name': i['name'] + ' Williams'})
Upvotes: 0
Reputation: 43024
I'm assuming you want to alter it in-place. You don't need to make a new dict.
for d in inlist:
d["name"] += " Williams"
Is all you have to do.
Upvotes: 0
Reputation: 208475
You need to create a new dictionary on each iteration of the loop, otherwise on each iteration you modify and append the same object to new_li
:
>>> li = [{'name': 'Peter'}, {'name': 'Anna'}]
>>> new_li = []
>>> for i in li:
... new_li.append({'name': i['name'] + ' Williams'})
...
>>> new_li
[{'name': 'Peter Williams'}, {'name': 'Anna Williams'}]
Upvotes: 0