We have two lists, A and B:
A = ['a','b','c']
B = [1, 2]
Is there a pythonic way to build the set of all maps between A and B containing 2^n (here 2^3=8)? That is:
[(a,1), (b,1), (c,1)]
[(a,1), (b,1), (c,2)]
[(a,1), (b,2), (c,1)]
[(a,1), (b,2), (c,2)]
[(a,2), (b,1), (c,1)]
[(a,2), (b,1), (c,2)]
[(a,2), (b,2), (c,1)]
[(a,2), (b,2), (c,2)]
Using itertools.product
, it's possible to get all the tuples:
import itertools as it
P = it.product(A, B)
[p for p in P]
Which gives:
Out[3]: [('a', 1), ('a', 2), ('b', 1), ('b', 2), ('c', 1), ('c', 2)]
You can do this with itertools.product
and zip
from itertools import product
print [zip(A, item) for item in product(B, repeat=len(A))]
Output
[[('a', 1), ('b', 1), ('c', 1)],
[('a', 1), ('b', 1), ('c', 2)],
[('a', 1), ('b', 2), ('c', 1)],
[('a', 1), ('b', 2), ('c', 2)],
[('a', 2), ('b', 1), ('c', 1)],
[('a', 2), ('b', 1), ('c', 2)],
[('a', 2), ('b', 2), ('c', 1)],
[('a', 2), ('b', 2), ('c', 2)]]
product(B, repeat=len(A))
produces
[(1, 1, 1),
(1, 1, 2),
(1, 2, 1),
(1, 2, 2),
(2, 1, 1),
(2, 1, 2),
(2, 2, 1),
(2, 2, 2)]
Then we pick each element from the product and zip it with A
, to get your desired output.
import itertools as it
A = ['a','b','c']
B = [1, 2]
for i in it.product(*([B]*len(A))):
print(list(zip(A, i)))
outputs:
[('a', 1), ('b', 1), ('c', 1)]
[('a', 1), ('b', 1), ('c', 2)]
[('a', 1), ('b', 2), ('c', 1)]
[('a', 1), ('b', 2), ('c', 2)]
[('a', 2), ('b', 1), ('c', 1)]
[('a', 2), ('b', 1), ('c', 2)]
[('a', 2), ('b', 2), ('c', 1)]
[('a', 2), ('b', 2), ('c', 2)]
Not sure if it's very pythonic, it is if you look at it.product(*([B]*len(A)))
, because it uses multiple python-specific language features. But it's actually too cryptic to be pythonic... B is repeated n-times based on length of A and unpacked to the product-function.
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