When we compose a function that should deliver some operation and produce some result back, we regularly use the return statement for rendering the result.
The yield keyword in python is likewise used to return a value from a function(just like the return keyword) but this keyword also saves the state of the local variables of the function. And when the function is called repeatedly, the execution is originated from the yield statement performed last time.
Let's see a simple case and try to surmise what yield keyword does
x = 0
while x < 5:
# incrementing the value of x
x += 1
In the code above we have outlined a simple function that has a while loop and is yielding the present value of x and then increments it.
Let us say first things first. When we use a yield statement in a function then that function is called a Generator. A generator generates or yields values and cannot be termed a simple function preferably it is called an iterable i.e. by using a loop.
Now let's see both the cases,
# calling the above function directly
print("Simple function call: ", counter())
# should print 0
# and now let's use a loop to print values
print("Now lets try using a loop:")
for y in counter():
Simple function call: <generator object counter at 0x7f95fba4ba98>
Now lets try using a loop:
Some Points to Remember about yield Keyword
On the whole, the yield is a reasonably simple statement. Its principal job is to regulate the flow of a generator function in a way that’s comparable to return statements. As shortly discussed above, though, the Python yield statement has some tricks up its sleeve.
When you call a generator function, you yield a special iterator called a generator. You can designate this generator to a variable to handle it. When you call specific methods on the generator, such as next(), the code within the function is performed up to yield.
When the Python yield statement is run, the program ceases function execution and returns the yielded value to the one who called. (In contradiction, return terminates function execution altogether.) When a function is interrupted, the state of that function is stored. This covers any variable bindings local to the generator, the internal stack, any exception handling, and the instruction pointer,
This permits you to continue function execution whenever you call one of the generator’s methods. In this way, all function evaluation strikes back upright after the yield.
Think of the yield keyword as a clever return statement that retains what it did the last time and proceeds from there the next time. Like in the counter() function above, when we call it the initial time, it will return 0, but when we call it the following time, it will increment the value of x and then return 1, then we call it repeatedly, it will again increment the value of x and return the result 2 and so on unto the loop is finished.
When we use the yield keyword to return data from a function it begins saving the states of the local variable, as a consequence, the overhead of memory allocation for the variable in the following calls is saved. Also, in consecutive calls, the flow begins from the last yield statement executed which lessens time consumed. Thus we can quickly create iterable functions applying the yield keyword.