What is the difference between raise StopIteration and a return statement in generators?

slallum picture slallum · Jan 6, 2013 · Viewed 28.2k times · Source

I'm curious about the difference between using raise StopIteration and a return statement in generators.

For example, is there any difference between these two functions?

def my_generator0(n):
    for i in range(n):
        yield i
        if i >= 5:
            return

def my_generator1(n):
    for i in range(n):
        yield i
        if i >= 5:
            raise StopIteration

I'm guessing the more "pythonic" way to do it is the second way (please correct me if I'm wrong), but as far as I can see both ways raise a StopIteration exception.

Answer

Jon Clements picture Jon Clements · Jan 6, 2013

There's no need to explicitly raise StopIteration as that's what a bare return statement does for a generator function - so yes they're the same. But no, just using return is more Pythonic.

From: http://docs.python.org/2/reference/simple_stmts.html#the-return-statement (valid to Python 3.2)

In a generator function, the return statement is not allowed to include an expression_list. In that context, a bare return indicates that the generator is done and will cause StopIteration to be raised.

Or as @Bakuriu points out - the semantics of generators have changed slightly for Python 3.3, so the following is more appropriate:

In a generator function, the return statement indicates that the generator is done and will cause StopIteration to be raised. The returned value (if any) is used as an argument to construct StopIteration and becomes the StopIteration.value attribute.