If you are a beginner and have recently started learning to program then you must have come across the ‘yield’ keyword in Python.
There is a big possibility that you might feel confused about what it is! On the other hand, you might already know about it, then the other question that could arise in your mind is why use the ‘yield’ keyword in python when we can use the ‘return’ keyword.
This curiosity of yours has brought you to the right place. Because in this article we will be reading about the ‘yield’ keyword in Python. Thereby we will try to understand the scenarios when the usage of the ‘yield’ keyword can be beneficial to us as a programmer. We will eventually understand why we need to use the ‘yield’ keyword instead of using the ‘return’ keyword. Apart from this, we will also be introducing you to the concept of generators in Python.
One of the biggest dilemmas a beginner will ever come across in Python language is when to use the ‘return’ keyword and when to use the ‘yield’ keyword. Provided you know that both of these are used to return some value out of a function.
The above statement can be more accurately stated as:
the ‘yield’ keyword in python is used to make generator functions and usually returns generator objects.
Now, you must be wondering what exactly a generator function is. We’ll discuss it in the upcoming section.
A generator function is just like a normal function that is used to return some values but instead of using the usual return keyword, we make use of the yield keyword to return the value in the function. The values returned are generated spontaneously. If the body of a user-defined function contains the yield keyword, that function automatically acts as a generator function.
As soon as the ‘yield’ keyword is executed inside the function, it yields back a generator object. The generator object is iterable in nature. Also, it could be iterated only once as the items are produced randomly by the generator. These values are not stored fully in memory. Thereafter, the control of the function returns back to the caller.
We can print the items produced by the generator by either calling the next() method again and again or by iterating over the generator object using the for loop. Inside the generator function, the yield keyword helps to maintain the current state of the local variable in the function. Here, the function when called again starts executing from the last yield statement. It is beneficial as it doesn’t use much memory and also saves a lot of computational time.
Syntax of a generator function
Let’s work on an example to understand the functioning of generator function and yield keyword more clearly. Have a look at the below-given code snippet:
In the above-written code snippet, we have written a generator function that generates an odd number from a given list of numbers. We can observe the function consists of a yield statement that yields the value ‘i’.
When we make a call to the generator function, it returns us a generator object that can be verified by printing the value of the ‘gen’ variable. As the generator object is iterable we can obtain its value by iterating over it. And for that, we are using the next() method available in Python that is used to return the next value in an iterator.
Every time we call the next() method over the generator object, it yields a single value. After that, the control goes back to the calling statement. Also, we need to note the point that the value of the local variable ‘i’ does not get reset as the control flows back to the calling function. Here, the current state of the variable remains intact. And the next item in the generator gets printed.
As items are being generated on the fly and are not stored in memory, the memory is saved. Also, computation becomes faster because the loop doesn’t need to restart from the beginning again and again. The output of the above-written code is given below.
Reading the generated values using for loop
In the above code, we have used the next() method to read generated values again and again. In this section, we will be using the for loop to read the values generated by the generator. Let’s rewrite the previous code after making some changes:
Upon saving and executing the code the output will be generated as:
We can also notice from the output that when we retry to print the items stored inside the generator object in the form of a list, it only prints an empty list.
This verifies the fact that the items are generated spontaneously and can be iterated/ read only once. The items inside the generator object get removed from the memory afterward and are not placed permanently. To read/view those items once again, we have to again call the generator function.
Scenarios where usage of ‘yield’ keyword in python is beneficial to a programmer:
Given below are some pointers which discuss the usage of the ‘yield’ keyword in Python:
- Whenever we want to create a generator function, we can use the ‘yield’ keyword.
- When we want to generate an iterator sequence but don’t want to store the entire sequence into memory so that memory can be saved.
- To save our computational time because the current state of the local variable is saved and execution resumes from the last yield statement.
- To return data having a really large size.
yield statement vs. return statement
In the following section, we have made a detailed comparison between both of these statements which are placed in the table given below:
|return keyword||yield keyword|
|We usually use the return keyword inside normal user-defined functions.||We usually use the yield keyword inside the generator function.|
|You can use the return keyword to return a specific value in a normal function when the function gets called.||You can use the yield keyword to return a generator object when the function is called.|
|Items returned occupy space in the memory.||No memory is allocated to the items returned by the yield keyword.|
|Items returned can be iterated again and again as they are saved onto memory.||Items returned can be iterated only once.|
|After execution of the return statement inside the function, function execution terminates. And the control flows back to the caller. When we make a call to it again, it starts executing from the beginning.||After execution of the yield statement, the function execution halts. And the value returns to the caller. When we call the function again, it starts executing from the last yield statement where it left off.|
|Execution time is less as compared to yield when we perform operations on large data.||Execution time is faster.|
|It is convenient when the size of data is small.||
As memory usage is less, it is very useful when we want to deal with large datasets.
Test your understanding of the yield keyword in python covered in this article, attempt these practice questions now:
Question 1. What does the ‘yield’ statement return in a Python program?
- Generator object
Correct Answer: (iii)
The yield statement returns us a generator object.
Question 2. Pick the correct output of the below-given code snippet?
op = generate(100)
- Function running
Correct Answer: (iv)
The first print statement execution, makes the local variable hold the value 100. So, firstly, the generator function will yield the value 100+1 = 101. Thereafter, the control flows back to the calling function.
Again after the execution of the second print statement, the generator function resumes from the last yield statement. Thus the print statement will print ‘Function running’ followed by 102. One must not get confused that the state got changed to 101; the current state of the local variable is still 100, so finally, the print statement prints the value 100+2 = 102.
Question 3. Pick the correct output of the below given code snippet?
for i in range(7):
gen = func(False)
- No output is printed
Correct Answer: (ii) (0,1,2,3,4,5,6)
False parameters passed inside the func() function will not have any major effect on the execution of the function. The function gets triggered and the execution of the loop goes from 0 to 6 then the generator object is converted into a tuple.
Question 4. Which of these methods do we generally use with the generators?
- both (i) and (iii)
Correct Answer: (iv) both (i) and (iii)
We can use the send() method to send data from the caller to the generator function. While we use the next() method to make a request to the generator to return the next value.
Question 5. Which of these is not an example of the advantages of using the ‘yield’ keyword?
- It reduces computational time.
- The yield keyword saves memory.
- It helps in making a generator.
- None of these
Correct Answer: (iv) None of these