(newbie) N-uples from list of lists

Martin Miller ggrp1.20.martineau at dfgh.net
Wed Nov 30 18:24:52 EST 2005


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