P-Gn
P-Gn

Reputation: 24591

"named" iterators: zipping iterators to return values as a dictionary rather than a tuple

I would like to combine several iterators together, however instead of having a tuple, I would like the values to be "named", as in a dict or a namedtuple. This would allow to gain some abstraction and robustness, since I would not need to knowing exactly what or how many values are returned, and in which order.

Is there a standard way to do this in python?

Upvotes: 0

Views: 44

Answers (1)

P-Gn
P-Gn

Reputation: 24591

I have not found such a tool in itertools, maybe somewhere else?

In the meantime this behavior could be implemented with this short function:

def dictzip(**kwargs):
  for values in zip(*kwargs.values()):
    yield dict(zip(kwargs.keys(), values))

Then for example,

>>> name = ['Alice', 'Bob', 'Claire']
>>> age = [11, 22, 33]
>>> email = ['[email protected]', '[email protected]', '[email protected]']
>>> for val in dictzip(name=name, age=age, email=email):
...   print('{name} {age} {email}'.format(**val))
...
Alice 11 [email protected]
Bob 22 [email protected]
Claire 33 [email protected]

This can also be used to iterate over a dictionary, "structure-of-array"-style:

>>> people = {
...    'name': ['Alice', 'Bob', 'Claire'],
...    'age': [11, 22, 33],
...    'email': ['[email protected]', '[email protected]', '[email protected]']}
>>> for val in dictzip(**people):
...   print('{name} {age} {email}'.format(**val))
...
Alice 11 [email protected]
Bob 22 [email protected]
Claire 33 [email protected]

(Edited to integrate @YannVernier's suggestion on formatting)

Upvotes: 3

Related Questions