Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Cartesian Product of two lists (itertools)

Reply
Thread Tools

Cartesian Product of two lists (itertools)

 
 
Thorsten Kampe
Guest
Posts: n/a
 
      01-25-2009
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, , (1, 5, 7), (1, 5, , (2, 4, 7), (2, 4, , (2,
5, 7), (2, 5, ]

so far so good... Now...
>>> list(product(product(list1, list2), list3))

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

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
 
Reply With Quote
 
 
 
 
Mensanator
Guest
Posts: n/a
 
      01-25-2009
On Jan 25, 3:12�pm, Thorsten Kampe <(E-Mail Removed)> 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, , (1, 5, 7), (1, 5, , (2, 4, 7), (2, 4, , (2,
> 5, 7), (2, 5, ]
>
> so far so good... Now...>>> list(product(product(list1, list2), list3))
>
> [((1, 4), 7), ((1, 4), , ((1, 5), 7), ((1, 5), , ((2, 4), 7), ((2,
> 4), , ((2, 5), 7), ((2, 5), ]
>
> 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, , (1, 5, 7), (1, 5, , (2, 4, 7), (2, 4, , (2,
5, 7), (2, 5, ]
>>>

 
Reply With Quote
 
 
 
 
Terry Reedy
Guest
Posts: n/a
 
      01-26-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, , (1, 5, 7), (1, 5, , (2, 4, 7), (2, 4, , (2,
> 5, 7), (2, 5, ]
>
> so far so good... Now...
>>>> list(product(product(list1, list2), list3))

> [((1, 4), 7), ((1, 4), , ((1, 5), 7), ((1, 5), , ((2, 4), 7), ((2,
> 4), , ((2, 5), 7), ((2, 5), ]
>
> 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))

 
Reply With Quote
 
Mark Wooding
Guest
Posts: n/a
 
      01-26-2009
Thorsten Kampe <(E-Mail Removed)> writes:

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


[...]

> 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]
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Predictably Breaking Up a Cartesian Product Brad C++ 9 07-15-2010 08:52 PM
Cartesian product zfareed@umd.umich.edu C++ 2 02-11-2007 10:34 PM
cartesian product - next to last version walter a kehowski Ruby 11 08-13-2005 08:04 AM
cartesian product walter a kehowski Ruby 26 08-10-2005 01:35 PM
cartesian product... deancoo C++ 4 02-28-2005 11:50 PM



Advertisments