(newbie) N-uples from list of lists

Martin Miller ggrp1.20.martineau at dfgh.net
Fri Dec 2 08:50:12 EST 2005


I'd be interested in seeing the one liner using reduce you mentioned --
how it might be done that way isn't obvious to me.

Another aspect of Taschuk's solution I like and think is important is
the fact that it is truly iterative in the sense that calling it
returns a generator which will yield each of the combinations, one at
time.  All the others create and return all the combinations at once
(as I suspect the one liner using reduce you mention does, too).

As you point out, "best" is always in the eyes of the beholder.

"Best" regards, ;-)
-Martin

====
bonono at gmail.com wrote:
> Interesting, I found a reduce one liner(just one step further of
> Raymond's) easiest to understand and match my thinking about what the
> problem is about.
>
> That once again tell me that different people think and approach the
> problem differently. It is possible to talk about one "fastest" way,
> but many times there isn't such a thing of one "best" way.
>
> Martin Miller wrote:
> > FWIW, I found Steven Taschuk's solution easiest to understand regarding
> > the question posed in your original post -- namely how to solve the
> > problem non-recursively with generators -- because it was similar to my
> > own thinking about how to do it -- but suspect that Raymond Hettinger's
> > is the likely the "best" (as is usually the case ;-).
> >
> > Best,
> > -Martin
> >
> >
> > vd12005 at yahoo.fr wrote:
> > > great thanks to all.
> > >
> > > actually i have not seen it was a cross product... :) but then there
> > > are already few others ideas from the web, i paste what i have found
> > > below...
> > >
> > > BTW i was unable to choose the best one, speaking about performance
> > > which one should be prefered ?
> > >
> > > ### --------------------------------------------------
> > >
> > > ### from title: variable X procuct - [(x,y) for x in list1 for y in
> > > list2]
> > > ### by author:  steindl fritz
> > > ### 28 mai 2002
> > > ### reply by:   Jeff Epler
> > >
> > > def cross(l=None, *args):
> > >     if l is None:
> > >         # The product of no lists is 1 element long,
> > >         # it contains an empty list
> > >         yield []
> > >         return
> > >     # Otherwise, the product is made up of each
> > >     # element in the first list concatenated with each of the
> > >     # products of the remaining items of the list
> > >     for i in l:
> > >         for j in cross(*args):
> > >             yield [i] + j
> > >
> > > ### reply by:   Raymond Hettinger
> > >
> > > def CartesianProduct(*args):
> > >     ans = [()]
> > >     for arg in args:
> > >         ans = [ list(x)+[y] for x in ans for y in arg]
> > >     return ans
> > >
> > > """
> > > print CartesianProduct([1,2], list('abc'), 'do re mi'.split())
> > > """
> > >
> > > ### from:
> > > http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/159975
> > > ### by: Raymond Hettinger
> > >
> > > def cross(*args):
> > >     ans = [[]]
> > >     for arg in args:
> > >         ans = [x+[y] for x in ans for y in arg]
> > >     return ans
> > >
> > > ### from:
> > > http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/159975
> > > ### by: Steven Taschuk
> > > """
> > > Iterator version, Steven Taschuk, 2003/05/24
> > > """
> > > def cross(*sets):
> > >     wheels = map(iter, sets) # wheels like in an odometer
> > >     digits = [it.next() for it in wheels]
> > >     while True:
> > >         yield digits[:]
> > >         for i in range(len(digits)-1, -1, -1):
> > >             try:
> > >                 digits[i] = wheels[i].next()
> > >                 break
> > >             except StopIteration:
> > >                 wheels[i] = iter(sets[i])
> > >                 digits[i] = wheels[i].next()
> > >         else:
> > >             break




More information about the Python-list mailing list