[Python-ideas] "Iteration stopping" syntax [Was: Is this PEP-able? for X in ListY while conditionZ:]
Nick Coghlan
ncoghlan at gmail.com
Mon Jul 1 03:30:30 CEST 2013
On 1 July 2013 10:59, Steven D'Aprano <steve at pearwood.info> wrote:
> So I think the missing piece is that generators are actually iterators.
> Since raising StopIteration is the official way to halt an iterator, it's
> also the (or at least, an) official way to halt a generator, and not a quirk
> of the implementation.
Yeah, the reason Andrew's proposed fix to the comprehension semantics
makes sense is the fact that exactly *where* StopIteration gets raised
during a "__next__" invocation is supposed to be completely opaque
from the point of view of the iterator protocol:
while True:
try:
x = next(itr):
except StopIteration:
break
# Process x...
The caught "StopIteration" could come from:
- a generator iterator frame terminating
- a generator iterator explicitly raising StopIteration
- a sequence iterator triggering IndexError
- a sentinel iterator noticing the sentinel value
- any other __next__ method raising StopIteration
When I did the conversion to "make [x for x in y] merely an optimised
version of list(x for x in y)" change for Python 3, I know I missed
the fact that part of that change involved moving the evaluation of
all of the subexpressions inside the implicit try/except that is part
of the iterator protocol, and I don't recall anyone else bringing it
up either. Even if it did come up, we must have dismissed it as
introducing too much overhead to set up the
almost-certainly-unnecessary try/except for each iteration.
Fortunately, Andrew is right that we can avoid that overhead and use a
single try/except to cover the whole comprehension, which is a nice
and cheap change.
Cheers,
Nick.
More information about the Python-ideas
mailing list