1

I realize that the title of this question might not be immediately super clear, so on an example:
My dict contains lists as follows (assume there's nothing else in it):

packed = {
    'names': ['a', 'b', 'c', 'd'],
    'values': ['A', 'B', 'C', 'D']
}

What I want to do is to iterate over each of these lists (as many as there might be) in parallel, but so that during each iteration I have a dict with a single element of each list. I imagine something like this:

for pack in smartIterate(packed): #how to "smartIterate"?
    print(pack['names'], pack['values'])
    #pack is equal to {'names':'a', 'values':'A'} in the first iteration

printing out that:

a, A
b, B
c, C
d, D

I realize this can be done with explicitly iterating over the length of one sublist and constructing a dict during each iteration:

for i in range(len(packed.values()[0])):
    pack = dict(zip(packed.keys(),[v[i] for v in packed.values()]))

but it feels like there is a cleaner, more efficient - pythonic - way to do that.

Similar questions:

  • this didn't clearly involve iterating over lists contained within a dict - mine is specifically about it,
  • this didn't involve parallel lists within a dict,
  • this didn't involve dicts.
Przemek D
  • 654
  • 6
  • 26
  • Possible duplicate of [Pythonic iteration over multiple lists in parallel](https://stackoverflow.com/questions/21911483/pythonic-iteration-over-multiple-lists-in-parallel) – ndmeiri Jun 15 '18 at 11:39
  • Not a duplicate, as the crucial part of this problem is to have those parallel values in a dict whose keys distinguish which list did the values come from. – Przemek D Jun 15 '18 at 11:41

1 Answers1

3

You can directly use zip with dict.values

Ex:

packed = {
    'names': ['a', 'b', 'c', 'd'],
    'values': ['A', 'B', 'C', 'D']
}

keysValue = packed.keys()
for pack in zip(*packed.values()): 
    print( dict(zip(keysValue, pack)) )

Output:

{'values': 'A', 'names': 'a'}
{'values': 'B', 'names': 'b'}
{'values': 'C', 'names': 'c'}
{'values': 'D', 'names': 'd'}

Or in a one line using list comprehension

keysValue = packed.keys()
print( [dict(zip(keysValue, pack)) for pack in zip(*packed.values())] )
#[{'values': 'A', 'names': 'a'}, {'values': 'B', 'names': 'b'}, {'values': 'C', 'names': 'c'}, {'values': 'D', 'names': 'd'}]
Rakesh
  • 81,458
  • 17
  • 76
  • 113
  • I am aware of that, but this doesn't give me an intermediate dict. `pack` is supposed to be `{'names': 'a', 'values': 'A'}` during every iteration (example given for the first iter). I will highlight the relevant sentence in my question to make this more clear. – Przemek D Jun 15 '18 at 11:36
  • 1
    Updated snippet is that what you want? – Rakesh Jun 15 '18 at 11:37
  • Yes! The list comprehension one-liner is particularly pretty. Thanks :) – Przemek D Jun 15 '18 at 11:45