[Python-ideas] "Iteration stopping" syntax [Was: Is this PEP-able? for X in ListY while conditionZ:]

Nick Coghlan ncoghlan at gmail.com
Sun Jun 30 07:45:53 CEST 2013


On 30 June 2013 14:53, Andrew Barnert <abarnert at yahoo.com> wrote:
> If you don't raise an exception through a listcomp, that cost is basically running one more opcode and loading a few more bytes into memory. It adds less than 1% for even a trivial comp that loops 10 times, or for a realistic but still simple comp that loops 3 times.

Comprehensions translate to inline loops. The fact that the "stop()"
hack works for generator expressions is just a quirky result of the
line between "return" and "raise StopIteration" in a generator
function being extraordinarily blurry - it has nothing to with
breaking out of a loop. That's why the stop() hack terminates a nested
genexp completely, rather than just breaking out of the innermost
loop:

>>> def stop():
...     raise StopIteration
...
>>> list((x, y) for x in range(10) for y in range(10) if y < 3 or stop())
[(0, 0), (0, 1), (0, 2)]

>>> def greturn():
...     for x in range(10):
...         for y in range(10):
...             if y >= 3: return
...             yield x, y
...
>>> list(greturn())
[(0, 0), (0, 1), (0, 2)]

>>> def graise():
...     for x in range(10):
...         for y in range(10):
...             if y >= 3: raise StopIteration
...             yield x, y
...
>>> list(graise())
[(0, 0), (0, 1), (0, 2)]

Note how all three produce the same output, and how both loops
terminate immediately when the return/raise is encountered.

You can't get the same semantics for other comprehensions without
introducing the yield/return distinction, which is astonishingly slow
by comparison (as you need to suspend and resume the generator frame
on each iteration). The overhead of that is only worth it when the
cost of having the entire result in memory at the same time is
prohibitive.

Cheers,
Nick.

--
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-ideas mailing list