[Jewett, Jim J]
t1 = (1,2,3) t2 = ("a", "b", "c") t3 = ("first", "second", "third")
(x,y,z for x in t1 for y in t2 for z in t3)
Do What I Mean is the crossproduct, 27 elements long, which you get with a list comprehension.
Well, that expression by itself will result in a generator-iterator getting created, with no actual results. If you put it in a context that drives generation, then it will deliver 27 results, and regardless of whether early-binding, late-binding, or mostly-late binding is used (although the latter two are sensitive to changes in the bindings for t2 and t3, if any such occur between the time the genexp is created and the time the genexp is driven). For mostly-late binding, it's the same as this Python program today (stuffing the genexp in a list() call to force it to do something): """ t1 = (1,2,3) t2 = ("a", "b", "c") t3 = ("first", "second", "third") def __g(primary): for x in primary: for y in t2: for z in t3: yield x, y, z print list(__g(t1)) """ Try running that, and see what you get.
This will happen if at least (all but one) generators are pre-evaluated.
There are no generators in your example, apart from the one created by the genexp itself. You may be confusing generators with iterable objects.
It will also happen if at least (all but one) generators are restarted after they raise StopIterator.
Doing strictly what happens today gets only
(1,'a',"first"), (1,'a',"second"), (1,'a',"third")
No -- run the above. You'll get the 27 you expect.
because t3 has raised StopIteration by the time t1 or t2 advance.
The innermost "for" loop swallows StopIteration each of the 9 times it occurs, and the outer for loops never see it. They keep going. This is how "for" loops always work (nothing is changing wrt that).