0

From a list of n lists, each having different numbers of element, I want to get all possible combinaison.

I make an example to help understand my problem:

If I have a list of lists like this:

a = [['a','b'], ['c','d'],['e','f','g']]

I would like to get something like this:

[[('a', 'c', 'e')],
 [('a', 'c', 'f')],
 [('a', 'c', 'g')],
 [('a', 'd', 'e')],
 [('a', 'd', 'f')],
 [('a', 'd', 'g')],
 [('b', 'c', 'e')],
 [('b', 'c', 'f')],
 [('b', 'c', 'g')],
 [('b', 'd', 'e')],
 [('b', 'd', 'f')],
 [('b', 'd', 'g')]]

I get that with this:

list((zip(x,y,z) for x in a[0] for y in a [1] for z in a[2]))

Now I would like a function to do the same thing with any list of lists I pass too it. (No list is empty)

Something recursive like that can maybe work, but I have a hard time figure it out and something less complex and faster is maybe possible.

I found a solution in java here, but I don't know java and I can't translate it.

Community
  • 1
  • 1
Data_addict
  • 300
  • 1
  • 9

2 Answers2

3

There's an itertools.product function for this. Just unpack your list as arguments:

>>> from itertools import product
>>> list(product(*a))
[('a', 'c', 'e'), ('a', 'c', 'f'), ('a', 'c', 'g'), ('a', 'd', 'e'), ('a', 'd', 'f'), ('a', 'd', 'g'), ('b', 'c', 'e'), ('b', 'c', 'f'), ('b', 'c', 'g'), ('b', 'd', 'e'), ('b', 'd', 'f'), ('b', 'd', 'g')]
zch
  • 14,931
  • 2
  • 41
  • 49
  • OP wished for the tuples to be wrapped in a list, I think. – Jonathan Eunice Dec 03 '14 at 22:47
  • @JonathanEunice, I doubt it, I think using it in example was because that's what `zip` returned, not what he intended. – zch Dec 03 '14 at 22:51
  • I agree it's quite unnecessary--the tuples should do just fine as first-level containers. I was just going by "I would like to get something like this:" followed by the boxed examples. – Jonathan Eunice Dec 03 '14 at 22:55
  • The tuples don't need to be wrapped, it an artefact of the way I found to do it. Thanks for your fast answer. – Data_addict Dec 03 '14 at 23:14
0
from itertools import product

[[combo] for combo in product(*a)]

Yields:

[[('a', 'c', 'e')],
 [('a', 'c', 'f')],
 [('a', 'c', 'g')],
 [('a', 'd', 'e')],
 [('a', 'd', 'f')],
 [('a', 'd', 'g')],
 [('b', 'c', 'e')],
 [('b', 'c', 'f')],
 [('b', 'c', 'g')],
 [('b', 'd', 'e')],
 [('b', 'd', 'f')],
 [('b', 'd', 'g')]]

So for a function, you just need:

def boxed_product(somelists):
    return [[combo] for combo in product(*somelists)]
Jonathan Eunice
  • 21,653
  • 6
  • 75
  • 77