StopIteration in the if clause of a generator expression
Raymond Hettinger
vze4rx4y at verizon.net
Fri Apr 1 11:34:32 EST 2005
[Peter Otten]
> 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?
I would call it an unfortunate assymmetry -- one the never comes up unless
you're up to no good ;-)
In a way, both behave identically. They both raise StopIteration. In the case
of the generator expression, that StopIteration is intercepted by the enclosing
list() call. That becomes obvious if you write a pure python equivalent for
list:
def lyst(s):
it = iter(s)
result = []
try:
while 1:
result.append(it.next())
except StopIteration: # guess who trapped StopIter
return result
Raymond Hettinger
More information about the Python-list
mailing list