StopIteration in the if clause of a generator expression

Bengt Richter bokr at oz.net
Fri Apr 1 16:14:20 EST 2005


On Fri, 01 Apr 2005 16:34:32 GMT, "Raymond Hettinger" <vze4rx4y at verizon.net> wrote:

>[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
>
>
I assumed that all standard sequence consumers (including list, of course) would intercept
the StopIteration of a sequence given them in the form of a generator expression, so your
lyst example would have an analogue for other sequence consumers as well, right?
I.e., there's not a hidden list(genex) in those others I would hope ;-)

E.g., "in" in my toy exposed more clearly, using Peter's stop:

 >>> def show(x): print x,; return x
 ...
 >>> def stop(): raise StopIteration
 ...
 >>> 2 in (x for x in xrange(5) if show(x)<4 or stop())
 0 1 2
 True
 >>> 7 in (x for x in xrange(5) if show(x)<4 or stop())
 0 1 2 3 4
 False

BTW I notice that this also nicely shortcuts when the 2 is found.

Regards,
Bengt Richter



More information about the Python-list mailing list