Welcome to another tutorial, here you will learn about the yield keyword in Python.
During coding, if we write a function that should perform some operation and provide some result, in python, the return statement is generally used to return the expected result.
However, the yield keyword in python is typically used to return a value from a function similar to the return, but this keyword also maintains the state of the local variables of the function, also when the function is called again, the execution starts from the yield statement executed last time again.
Check out the example below:
def counter():
x = 0
while x < 5:
yield x
# incrementing the value of x
x += 1
From the example above, we defined a simple function that has a while loop and is yielding the current value of x and then increments it thereafter.
Now, let’s start somewhere, if we use a yield statement in a function, as such the function is known as a Generator. This is will be discussed in a subsequent tutorial.
However, a generator generates or yields values and cannot be called a simple function, instead, it is called an iterable, meaning using a loop, e.g the for loop. Check out the example below:
# calling the above function directly
print("Simple function call: ", counter()) # should print 0
# and now lets use a loop to print values
print("Now lets try using a loop:")
for y in counter():
print(y)
Output:
Simple function call: <generator object counter at 0x7f95fba4ba98>
Now lets try using a loop:
0
1
2
3
4
You should consider the yield keyword as a smart return statement, that remembers what it did last and continues from there the next time.
Also, quite similar to the counter() function above, if we call it the first time, it will return 0, but when we call another time, it will increment the value of x and then return 1, and we call it again, it will increment the value of x again and return the result 2 and this continues until the loop is completed.
By using the yield keyword, we can make our function iterable, just as discussed above. Also, in dealing with iterable, we can make use of the next() method for iterating the next element. Check out the first example below:
Example:
# A simple generator function
def new_gen():
n = 1
print('First execution...')
# Generator function contains yield statements
yield n
n += 1
print('Second execution...')
yield n
n += 1
print('Third execution...')
yield n
# main method
if __name__=='__main__':
# new_gen function will not execute, but return a generator
x = new_gen()
# calling next on variable x
print(next(x))
# calling next on variable x
print(next(x))
# calling next on variable x
print(next(x))
Output:
First execution...
1
Second execution...
2
Third execution...
3
In our example above, a multiple yield statement was used to save the state of the execution of the function ( or generator) new_gen() in a way that the next time that the function is called the execution is called, the execution begins from where it last stopped.
Now, let’s try to add one more print(next(x)) statement to the example above and you will see the StopIteration exception which an iterator returns when there is no more data to iterate over.
Example:
For this example, we will be using yield the keyword in a function to count the occurrence of a word in a sentence.
# function to count number of times a word occurs
def count_words(test_string, word) :
for i in test_string:
if i == word:
yield i
# initializing the string
test_string = "The big brown bear, was big enough to hide the big hut behind it"
# look for the word
word = "big"
# initialize count
count = 0
# using split to break the sentence into list of words
for j in count_words(test_string.split(), word):
count = count + 1
print ("The count is ", count)
Output:
The count is 3
If we use the yield keyword in this example, it helps us to simplify the code for searching a word in a list of words and increasing the count at the same time, because the yield keyword will remember the last state and thus will not iterate over the words which are checked already.