KaliMa
KaliMa

Reputation: 2060

Iterating through all combinations across many iterables

for item1 in dict[1]:
   for item2 in dict[2]:
     for item3 in dict[3]:
        and so on

Let's say there are n keys in dict. Is there a way to generate n items at a time with a one-liner using itertools?

in other words can I replicate the above code with something in itertools?

Upvotes: 2

Views: 111

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1122322

Use itertools.product():

from itertools import product

for combo in product(*somedict.values()):

Note that the values are returned in current dictionary order, which is arbitrary. If you need a specific ordering of the keys, you'll need to provide that order:

keys = ('foo', 'bar', 'baz')
for combo in product(*(somedict[k] for k in keys)):

If you wanted a dictionary with the same keys again, use zip():

for combo in product(*somedict.values()):
    newdict = dict(zip(somedict.keys(), combo))

Demo:

>>> from itertools import product
>>> somedict = {'foo': [1, 2], 'bar': ['a', 'b', 'c'], 'baz': [42, 81]}
>>> for combo in product(*somedict.values()):
...     print combo
... 
(42, 1, 'a')
(42, 1, 'b')
(42, 1, 'c')
(42, 2, 'a')
(42, 2, 'b')
(42, 2, 'c')
(81, 1, 'a')
(81, 1, 'b')
(81, 1, 'c')
(81, 2, 'a')
(81, 2, 'b')
(81, 2, 'c')
>>> for combo in product(*somedict.values()):
...     print dict(zip(somedict.keys(), combo))
... 
{'bar': 'a', 'foo': 1, 'baz': 42}
{'bar': 'b', 'foo': 1, 'baz': 42}
{'bar': 'c', 'foo': 1, 'baz': 42}
{'bar': 'a', 'foo': 2, 'baz': 42}
{'bar': 'b', 'foo': 2, 'baz': 42}
{'bar': 'c', 'foo': 2, 'baz': 42}
{'bar': 'a', 'foo': 1, 'baz': 81}
{'bar': 'b', 'foo': 1, 'baz': 81}
{'bar': 'c', 'foo': 1, 'baz': 81}
{'bar': 'a', 'foo': 2, 'baz': 81}
{'bar': 'b', 'foo': 2, 'baz': 81}
{'bar': 'c', 'foo': 2, 'baz': 81}

Upvotes: 3

Related Questions