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 ==== [EMAIL PROTECTED] 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 > > > > > > [EMAIL PROTECTED] 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 -- http://mail.python.org/mailman/listinfo/python-list