I have two lists:
a = ['a', 'b']
b = [1, 2, 3]
I want to get the combinations produced between the elements of list b
and the elements of list a but treating elements of a
as pairs (or triples etc. etc.) as the example below which gives len(b) ** len(a)
number of combinations.
c = ["a_1 b_1", "a_1 b_2", "a_1 b_3", "a_2 b_1", "a_2 b_2", "a_2 b_3", "a_3 b_1", "a_3 b_2" "a_3 b_3"]
I have tried to use itertools.product
(as described here) but this will give only the 6 possible combinations.
You can use itertools.product(..)
but specify repeat
to be repeat=len(a)
. So you can use:
from itertools import product
def mul_product(a,b):
for tup in product(b,repeat=len(a)):
yield ' '.join('%s_%s'%t for t in zip(a,tup))
The product(..)
will generate tuples like:
>>> list(product(b,repeat=len(a)))
[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]
So here the first element of the tuple is the one that is attached to a_
, the second one to b_
. Now we zip(..)
them together with the a
list, producing:
>>> list(map(lambda bi:list(zip(a,bi)),product(b,repeat=len(a))))
[[('a', 1), ('b', 1)], [('a', 1), ('b', 2)], [('a', 1), ('b', 3)], [('a', 2), ('b', 1)], [('a', 2), ('b', 2)], [('a', 2), ('b', 3)], [('a', 3), ('b', 1)], [('a', 3), ('b', 2)], [('a', 3), ('b', 3)]]
Now it is only a matter of formatting ('%s_%s'%t
), and ' '.join(..)
ining them together and yield
them (or you can use list comprehension to produce a list).
The result for your sample input is:
>>> list(mul_product(a,b))
['a_1 b_1', 'a_1 b_2', 'a_1 b_3', 'a_2 b_1', 'a_2 b_2', 'a_2 b_3', 'a_3 b_1', 'a_3 b_2', 'a_3 b_3']
Note that the elements here are generated lazily. This can be useful if you are for instance only interested in the first k
ones, or when you do not want to generate all of them at once.
You could explicitly create your pairwise items using itertools.product
, then operate on those pairs again with itertools.product
import itertools
a = ['a', 'b']
b = [1, 2, 3]
pairs = [list(itertools.product([ai], b)) for ai in a]
pairs
will contain the two lists that can fed into itertools.product
again.
list(itertools.product(*pairs))
The result is:
[(('a', 1), ('b', 1)),
(('a', 1), ('b', 2)),
(('a', 1), ('b', 3)),
(('a', 2), ('b', 1)),
(('a', 2), ('b', 2)),
(('a', 2), ('b', 3)),
(('a', 3), ('b', 1)),
(('a', 3), ('b', 2)),
(('a', 3), ('b', 3))]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With