0
l1 = [1, 2, 3]
l2 = ['foo', 'bar', 'test']


z1 = zip(l1,l2)
list(z1)
[(1, 'foo'), (2, 'bar'), (3, 'test')]

That's a sample of my code. Now I want to map (??) each value of the tuples to either id, or name. So I can get a result like :

[('id':1, 'name':'foo'), ('id':2, 'name':'bar'), ('id':3, 'name':'test')]

What I did is :

>>> result = []
>>> for i in zip(l1,l2):
...     d['id'] = i[0]
...     d['name'] = i[1]
...     result.append(d)
>>> result
[{'id': 3, 'name': 'test'}, {'id': 3, 'name': 'test'}, {'id': 3, 'name': 'test'}]

but 1st) it doesn't works and 2nd) not pythonic at all as far as I can tell...

I don't understand why the loop above doesn't works. If I do :

>>> for i in zip(l1,l2):
...     print(i[0], i[1])
... 
1 foo
2 bar
3 test

it iterates every item without problem and the append() I used above with the list shouldn't cause any problems...

mt0s
  • 5,781
  • 10
  • 42
  • 53

3 Answers3

1

You can write that for loop pythonically using a dict comprehension:

[{'id': id, 'name': name} for id,name in zip(l1, l2)]

Depending on how complex this dict actually is, and what you want to do with it, you might want to consider using a simple class instead.

sapi
  • 9,944
  • 8
  • 41
  • 71
1

Id d is your dictionary what you are doing is replacing the values of the keys(id & name) of the dictionary d and your are appending it to a list.

To create a list of dictionary you can use a list comprehension like

l1 = [1, 2, 3]
l2 = ['foo', 'bar', 'test']
result = [{'id': i[0], 'name':i[1]} for i in zip(l1,l2)]
Thiru
  • 3,293
  • 7
  • 35
  • 52
1

Your solution doesn't work because you are "overriding" the dict at each step :

>>> for i in zip(l1,l2):
...   d['id']=i[0]
...   d['name']=i[1]
...   r.append(d)
...   print r
...
[{'id': 1, 'name': 'foo'}]
[{'id': 2, 'name': 'bar'}, {'id': 2, 'name': 'bar'}]
[{'id': 3, 'name': 'test'}, {'id': 3, 'name': 'test'}, {'id': 3, 'name': 'test'}]

One way to go is to "reset" your dict at the beginning of each step:

>>> for i in zip(l1,l2):
...   d={}
...   d['id']=i[0]
...   d['name']=i[1]
...   r.append(d)
...   print r
...
[{'id': 1, 'name': 'foo'}]
[{'id': 1, 'name': 'foo'}, {'id': 2, 'name': 'bar'}]
[{'id': 1, 'name': 'foo'}, {'id': 2, 'name': 'bar'}, {'id': 3, 'name': 'test'}]

But as others pointed out, [{'id': id, 'name': name} for id, name in zip(l1, l2)] is more pythonic.

And I don't know if you could use it, but you could build your dict from your zip:

>>> dict(zip(l1, l2))
{1: 'foo', 2: 'bar', 3: 'test'}
fredtantini
  • 15,966
  • 8
  • 49
  • 55
  • look at this SO [link](http://stackoverflow.com/questions/8744113/python-list-by-value-not-by-reference) for the append copy. – Thiru Jul 30 '14 at 07:57