StopIteration in the if clause of a generator expression

Peter Otten __peter__ at web.de
Fri Apr 1 05:04:11 EST 2005


To confuse a newbies and old hands alike, Bengt Richter wrote:

> Need something more straightforward, e.g., a wrapped one-liner:
> 
>  >>> def guess(n=3): print ("You're right!", 'No more tries for
>  >>> you!!!')[n-1 in
>  ...    (x for x in xrange(n) for t in [raw_input('Guess my name:
>  ')=='Ben']
>  ...    if not t or iter([]).next())]
>  ...
>  >>> guess()

To make it a bit clearer, a StopIteration raised in a generator expression
silently terminates that generator:

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

In a list comprehension, on the other hand, it is propagated:

>>> [i for i in range(10) if i < 5 or stop()]
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 1, in stop
StopIteration

Is that an intentional difference?

Peter




More information about the Python-list mailing list