2

I'm trying to learn python, reading by the book Learning Python, and came across the section of using the return statement in generators, and I'm finding it difficult to wrap my head around it.

It says that while using the return statement in a generator function, it will produce a StopIteration exception to be raised, effectively ending the iteration. If a return statement were actually to make the function return something, it would break the iteration protocol.

Here's the code sample

def geometric_progression(a, q):
    k = 0
    while True:
        result = a * q**k
        if result <= 100000:
            yield result
        else:
            return
        k += 1

for n in geometric_progression(2,5):
    print(n)

Can anyone please explain it, and also how to use it further in any other context. Provide extra examples, if you may.

phawk
  • 23
  • 1
  • 5
  • Just think of it as stopping the iteration early. In this case, the condition `result <= 100000` stops the generator from yielding a result bigger than `100000`, which is kind of contrived, since you could have made the while-loop `while <= 100000` to achieve the same effect (with some appropriate initial value for `result`). Honestly, I don't think it's used very much, but there are cases where you want to stop iteration immediately where it might come in handy. – juanpa.arrivillaga Feb 10 '17 at 22:45
  • Possible duplicate of [Return in generator together with yield in Python 3.3](http://stackoverflow.com/questions/16780002/return-in-generator-together-with-yield-in-python-3-3) – Chris_Rands Feb 10 '17 at 22:47
  • @Chris_Rands -- FWIW, this is _slightly_ different than that question. That is specifically asking what `return value` means whereas this is asking about bare return as well (and is therefore applicable to python2.x as well). I agree though -- They're _very_ similar and I could understand if this ended up being closed as a dupe :-) – mgilson Feb 10 '17 at 22:49

1 Answers1

4

return in a generator is just syntactic sugar for raise StopIteration. In python 3.3(?)+, you can also return a value (return value == raise StopIteration(value)).

As for why you'd want to put it there, obviously raising a StopIteration means that the generator will stop yielding items. In other words, the generator is finished executing -- just like return signals the end of a function's execution. Similarly, anything which is iterating over the generator (e.g. a for loop) will understand that it should stop trying to get values from the generator.

The return value bit was added to support some workflows using co-routines IIRC. It's a pretty advanced feature but finds lots of usefulness in various async contexts.

mgilson
  • 300,191
  • 65
  • 633
  • 696