Quantcast

Cartesian Product of two lists (itertools)

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Cartesian Product of two lists (itertools)

Thorsten Kampe
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:

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]


Thorsten
--
http://mail.python.org/mailman/listinfo/python-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Cartesian Product of two lists (itertools)

mensanator@aol.com
On Jan 25, 3:12�pm, Thorsten Kampe <[hidden email]> 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:
>
> 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]
>
> Thorsten

Will this work for you?

>>> list4 = [(i,) for i in list3]

>>> list4
[(7,), (8,)]

>>> a = list(itertools.product(itertools.product(list1, list2), list4))
>>> a
[((1, 4), (7,)), ((1, 4), (8,)), ((1, 5), (7,)), ((1, 5), (8,)), ((2,
4), (7,)), ((2, 4), (8,)), ((2, 5), (7,)), ((2, 5), (8,))]

>>> def flatten(listOfLists):
    return tuple(itertools.chain.from_iterable(listOfLists))

>>> list5 = [flatten(i) for i in a]
>>> list5
[(1, 4, 7), (1, 4, 8), (1, 5, 7), (1, 5, 8), (2, 4, 7), (2, 4, 8), (2,
5, 7), (2, 5, 8)]
>>>
--
http://mail.python.org/mailman/listinfo/python-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Cartesian Product of two lists (itertools)

Terry Reedy
In reply to this post by Thorsten Kampe
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))

--
http://mail.python.org/mailman/listinfo/python-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Cartesian Product of two lists (itertools)

Mark Wooding
In reply to this post by Thorsten Kampe
Thorsten Kampe <[hidden email]> writes:

> [((1, 4), 7), ((1, 4), 8), ((1, 5), 7), ((1, 5), 8), ((2, 4), 7), ((2,
> 4), 8), ((2, 5), 7), ((2, 5), 8)]

[...]

> 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?!

Python has powerful destructuring capabilities:

        [(x, y, z) for ((x, y), z) in lopsided_list]

This seems simpler and is probably faster than a generalized flatten for
this size of problem, but I wouldn't use it to rearrange tuples with
more than four or five elements.

-- [mdw]
--
http://mail.python.org/mailman/listinfo/python-list
Loading...