[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 -- http://mail.python.org/mailman/listinfo/python-list