[Python-3000] Is this a bug with list comprehensions or not?
Terry Reedy
tjreedy at udel.edu
Thu Jul 10 19:11:12 CEST 2008
Antoine Pitrou wrote:
> Carl Johnson <carl <at> carlsensei.com> writes:
>> This raises the question, do we need both a ``break`` statement and
>> ``raise StopIteration``?
>> Can the former just be made into syntatic sugar
>> for the later? Or is this the hobgoblin of a little mind?
Yes, no, and ??.
One reason to use an iterator within a while loop instead of a for loop
is to do something other than break when the iterator signals that it
has nothing more. Similarly, if one iterates through it1 with a for
loop and uses it2.next() within the body, magically breaking when it2
ends could also be the wrong thing. In either case, 'continue' or
something else might be the right thing. One might be able to work
around magical breaks with clever use of iterator-oriented built-ins and
itertools, but such should not be required.
> Also, I don't see where consistency is improved. IMO, StopIteration is meant to
> be raised by the code which produces the iterator, not by the code consuming it
> - and even less by third-party, non-iterator related code. Otherwise it's an
> application bug.
>
> That is, in your example:
>
> >>> def f(x):
> ... if x > 5: raise StopIteration
> ...
> >>> list(x for x in range(100) if not f(x))
> [0, 1, 2, 3, 4, 5]
>
> f() certainly shouldn't raise a StopIteration. There's no reason for doing
> that, other than taking dirty implementation shortcuts and ending up with
> difficult to maintain code.
I had essentially the same thought about this. As I understood it, the
purpose of introducing a new built-in exception, StopIteration, along
with the new iterator protocol, was to give iterators a unique signal to
send to consumers that would not conflict with anything else then
existing. So it seems either a bug or abuse for non-iterators to hijack
the signal.
Terry Jan Reedy
More information about the Python-3000
mailing list