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