Cartesian Product of two lists (itertools)

Terry Reedy tjreedy at udel.edu
Mon Jan 26 02:20:05 CET 2009


Thorsten Kampe wrote:
> Hi,
> 
> is there a way to make itertools.product generate triples instead of 
> pairs from two lists?
> 
> For example:
>>>> list1 = [1, 2]; list2 = [4, 5]; list3 = [7, 8]
>>>> from itertools import product
>>>> list(product(list1, list2, list3))
> [(1, 4, 7), (1, 4, 8), (1, 5, 7), (1, 5, 8), (2, 4, 7), (2, 4, 8), (2, 
> 5, 7), (2, 5, 8)]
> 
> so far so good... Now...
>>>> list(product(product(list1, list2), list3))
> [((1, 4), 7), ((1, 4), 8), ((1, 5), 7), ((1, 5), 8), ((2, 4), 7), ((2, 
> 4), 8), ((2, 5), 7), ((2, 5), 8)]
> 
> Oops, pairs of pairs instead triples. Not what I wanted.
> 
> What's the best way to pre-process the arguments to "itertools.product" 
> or to post-process the result of "itertools.product" to get what I 
> want?!
> 
> I have an older utility which I would like to replace with 
> itertools.product. The old one uses a rather clumsy way to indicate that 
> a triple was wanted:

A pair of function, cart_pair, cart_trip, would have been better.
Or auto recognition of the number of sequences passed in.

> def cartes(seq0, seq1, modus = 'pair'):
>     """ return the Cartesian Product of two sequences """
>     if   modus == 'pair':
>         return [[item0, item1] for item0 in seq0 for item1 in seq1]
>     elif modus == 'triple':
>         return [item0 + [item1] for item0 in seq0 for item1 in seq1]

The second branch only produces a triple if seq0 is a sequence of pairs. 
  This must be called with something like
   res = cartes(cartes(list1,list2),list3,'triple')
Just replace that with your first only-once itertools call
   list(product(list1, list2, list3))




More information about the Python-list mailing list