Alpesh Valaki
Alpesh Valaki

Reputation: 1631

How yield identify that its iteration done once.?

I have read about yield at What does the "yield" keyword do in Python? keyword in python but i have one question that how system identity that yield iterated once.

def test_yield():
    name = 'Hello World!'
    for i in name:
        yield i

y= test_yield()

print "first yield",y
for c in y:
    print c

print "second yield",y
for c in y:
    print c  

Output

first yield <generator object test_yield at 0x7f4c2bc10be0>
H
e
l
l
o

W
o
r
l
d
!
second yield <generator object test_yield at 0x7f4c2bc10be0>

In output second time yield object printed but not iterate.so how program identity that its executed once?

Upvotes: 2

Views: 724

Answers (4)

Kishy Nivas
Kishy Nivas

Reputation: 673

When a generator function calls yield, the "state" of the generator function is frozen; the values of all variables are saved and the next line of code to be executed is recorded until next() is called again. Once it is, the generator function simply resumes where it left off. If next() is never called again, the state recorded during the yield call is (eventually) discarded.

Given that when the generator function reaches it's end, a StopIteration Exception is raised, making it exhausted hence you have to reload it, that is the reason it didn't iterate any values during the second call.

Note : for gets values by calling next() implicitly

Upvotes: 2

Artem Kryvonis
Artem Kryvonis

Reputation: 128

When you wrote y = test_yield() you initialize iterator and when you finish your iteration after first for c in y: the iterator was ended. You need to initialize once more like:

def test_yield():
      name = 'Hello World!'
      for i in name:
        yield i

y= test_yield()

print "first yield",y
for c in y:
    print c

# once again
y= test_yield()  

print "second yield",y
for c in y:
    print c  

Upvotes: 1

user6165050
user6165050

Reputation:

The first time the for calls the generator object created from your function, it will run the code in your function from the beginning until it hits yield, then it’ll return the first value of the loop. Then, each other call will run the loop you have written in the function one more time, and return the next value, until there is no value to return. In your second for loop, there's no more value to retrieve because you already wasted them.

For more insight as to what's happening behind the scenes, the for loop can be rewritten to this:

iterator = some_func()
try:
    while 1:
        print iterator.next()
except StopIteration:
    pass

Upvotes: 1

BoarGules
BoarGules

Reputation: 16952

Looping through an iterator "uses it up". So your first yield loop iterates through it and reaches the end. Just as if you opened a file and read all of the lines until EOF. After that, no matter how many times you call read(), you won't get more data, only EOF. Similarly, once your iterator has reached its last element, calling .next on it just raises StopIteration.

Upvotes: 3

Related Questions