On 31 January 2013 08:32, Nick Coghlan
On Tue, Jan 29, 2013 at 10:35 PM, Joao S. O. Bueno
wrote: On 29 January 2013 09:51, yoav glazner
wrote: Here is very similar version that works (tested on python27)
def stop(): next(iter([]))
list((i if i<50 else stop()) for i in range(100)) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]
This actually prompted an interesting thought for me. The statement-as-expression syntactic equivalent of the "else stop()" construct would actually be "else return", rather than "else break", since the goal is to say "we're done", regardless of the level of loop nesting.
I'm not sure if it is the goal to be able to break out of any level of nesting or at least that's not how I interpreted the original proposal. It is what happens for this stop() function but only because there's no other way. Personally I don't mind as I generally avoid multiple-for comprehensions; by the time I've written one out I usually decide that it would be more readable as ordinary for loops or with a separate function.
It just so happens that, inside a generator (or generator expression) raising StopIteration and returning from the generator are very close to being equivalent operations, which is why the "else stop()" trick works. In a 3.x container comprehension, the inner scope is an ordinary function, so the equivalence between returning from the function and raising StopIteration is lost.
I don't really understand what you mean here. What is the difference between comprehensions in 2.x and 3.x? Oscar