Gal Diskin wrote: > On Dec 13, 3:58 pm, Roberto Bonvallet <[EMAIL PROTECTED]> > wrote: > > Gal Diskin wrote: > > > Hi, > > > I am writing a code that needs to iterate over 3 lists at the same > > > time, i.e something like this: > > > > > for x1 in l1: > > > for x2 in l2: > > > for x3 in l3: > > > print "do something with", x1, x2, x3What's wrong with this? > > > > [...] > > > > > I'd be very happy to receive ideas about how to do this in one loop and > > > with minimal initialization (if at all required).def > > > cartesian_product(l1, l2, l3): > > for i in l1: > > for j in l2: > > for k in l3: > > yield (i, j, k) > > > > for (i, j, k) in cartesian_product(l1, l2, l3): > > print "do something with", i, j, k > > Nothing seriously wrong, but it's not too elegent.
I wonder why you think that. Many people here would consider it the height of elegance to take some complicated logic, writing a function encompassing the complicated parts, and ending up with simpler logic. That's what happens here. The cartesian_product solution above is not much longer than this syntax you proposed: for (i,j,k) in (a,b,c): use(i,j,k) (You can make the function name shorter if you want.) What is it that you find inelegant about this solution? Is it that you don't like extra function sitting there? Just put it in a module and import it. > Especially when the > number of lists you want to iterate over gets bigger (especially > because of the indentation in python). The function can be extended to allow arbitrary arguments. Here's a non-minmal recursive version. def cartesian_product(*args): if len(args) > 1: for item in args[0]: for rest in cartesian_product(*args[1:]): yield (item,) + rest elif len(args) == 1: for item in args[0]: yield (item,) else: yield () > As you noticed (an phrased > better than me), what I was wondering is if there is a way to iterate > over the cartesian product, but without actually doing all n for loops > but using a single "for" loop. Even if Python had a special syntax for it, it would still be looping internally. And there's almost no chance of there ever being a special syntax for it. First of all, it's very straightforward to do with functional solutions, as we've shown here. Second, compare the case of zip. Iteration in parallel (such as you would do with zip) is a lot more common than nested iteration (cartesian_product), but even parallel iteration doesn't have a special syntax, and th BDFL had declared that won't in Python 3.0. The best you could hope for is a built in function like zip, and that's doubtful. OTOH, something like this has decent shot of appearing in a standard functional or iterator module of some sort. > Thanks for replying me. You're welcome in advance. Also, one note about comp.lang.python and/or python-list: it's conventional here to put replies beneath the quoted text. This is for the benefit of future readers, so they don't have read conversations in reverse order. Carl Banks -- http://mail.python.org/mailman/listinfo/python-list