Bad_Coder
Bad_Coder

Reputation: 1029

Generator object with yield

I have found the below piece of code on the internet, with the actual output

def countdown(start):
   print start
   if start == 0:
      yield 0
   else:
      yield countdown(start -1)

g = countdown(3)
g.next()
g.next()

the output of the code is

3 StopIteration

Can anyone break this code down for me, Is next() skipping the sequence of the generator? I can't seem to understand the flow here

Upvotes: 0

Views: 1059

Answers (2)

Stefan Pochmann
Stefan Pochmann

Reputation: 28656

I don't think you found that code on the internet. You seem to be missing the entire point of that blog post, and if you use g = g.next() instead of g.next() like it's shown there, then it makes sense and it works.

But to answer your question, why it goes wrong the way it goes wrong when you do it like you did:

countdown yields exactly one thing, either 0 or another generator. g.next() fetches that one thing, and since you don't do anything with it, it's lost. And then, since g is still the original generator, and it already gave you the one thing it had to give, you get that StopIteration when you ask it for a second thing.

If instead you assign that second generator back to g like you should, then you can ask that generator to give you its one item. And so on.

Upvotes: 2

Jose Ricardo Bustos M.
Jose Ricardo Bustos M.

Reputation: 8174

Is this what you want?

def countdown(start):
  if start >= 0:
    yield start
    for i in countdown(start -1):
      yield i

g = countdown(3)
g.next()  #3
g.next()  #2
g.next()  #1
g.next()  #0
g.next()  #StopIteration

problem

yield countdown(start -1) return a generator and iteration then stop

Upvotes: 1

Related Questions