[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