Detailed explanation of yield in Python — the simplest and clearest explanation

What I make complaints about is what closely reasoned and well argued. First, I want to talk about the process of yield. I found that no one could simply let me know. When I was talking about Baidu, it was all the same, what parameters and what was passed. It was also the simplest and the easiest way to read the TM tutorial. I would like to ask if I have not considered the feelings of the readers.

Next is the topic

First of all, if you don’t have a preliminary understanding of yield, you can regard yield as “return”. This is intuitive. First of all, it is a return. What does the common return mean? It means to return a value in the program. After returning, the program will no longer run down. See it as a return, and then see it as a part of the generator (the function with yield is the real iterator). Well, if you don’t understand this, first consider yield as a return, and then look at the following program directly, you will understand all the meaning of yield:

def foo():
    print("starting...")
    while True:
        res = yield 4
        print("res:",res)
g = foo()
print(next(g))
print("*"*20)
print(next(g))

Just a few lines of code will let you understand what yield is

starting...
4
********************
res: None
4

I directly explain the code running order, which is equivalent to single step debugging of code

1. After the program starts to execute, because there is yield keyword in foo function, foo function will not really execute, but get a generator g (equivalent to an object) first

2. Until the next method is called, the foo function is formally executed. First, the print method in the foo function is executed, and then the while loop is entered

3. When the program encounters the yield keyword, think of yield as return. After a return of 4, the program stops and does not execute the assignment to res operation. At this time, the next (g) statement is executed, so the first two lines of output (the first is the result of print above while, and the second is the result of return) are the result of print (next (g)),

4. The program executes print (“*” * 20) and outputs 20*

5. Start to execute the following print (next (g)), This time is similar to the one above, but the difference is that this time starts from the place where the next program just stopped, that is, the assignment operation of res is to be executed. At this time, it should be noted that there is no value on the right side of the assignment operation (because the return just went out, and no parameter was passed to the left side of the assignment operation), so this time Res is assigned to none, so the next output is res:None ,

6. The program will continue to run in while, and it will encounter yield again. At this time, it will return 4, and then the program will stop. The output 4 of the print function is the return 4

 

Here you may understand the relationship and difference between yield and return. The function with yield is a generator, not a function. One function of this generator is the next function. Next is equivalent to the number generated in the “next step”. The place where the next starts this time is the place where the next stops last time. Therefore, when calling next, the generator It doesn’t start from the start of foo function. It just starts from the place where the last step stopped. After yield is met, return the number to be generated. This step ends.

****************************************************************************************************************************************

def foo():
    print("starting...")
    while True:
        res = yield 4
        print("res:",res)
g = foo()
print(next(g))
print("*"*20)
print(g.send(7))

Take another example of the send function of this generator. This example replaces the last line of the above example. The output result is as follows:

starting...
4
********************
res: 7
4

Let’s talk about the concept of the send function: at this time, you should pay attention to the purple word above, and why the value of res above is none, which becomes 7. Why? This is because send sends a parameter to res, because it is mentioned above that when return, 4 is not assigned to res, so you have to continue the assignment next time , we have to assign it to none. If we use send, when we start execution, we first assign 7 to res in the last execution (after return 4), and then perform the function of next. When we meet the next yield, the result of return is finished.

 

5. The program executes g. send (7), the program will continue to run down from the yield keyword line, and send will assign the value of 7 to the res variable

6. Because the send method contains the next () method, the program will continue to run down, execute the print method, and then enter the while loop again

7. When the program encounters the yield keyword again, yield will return the following value, and the program will pause again until the next method or send method is called again.

 

 

 

That’s the end. Let’s talk about why we use this generator because if we use list, it will take up more space, such as 0,1,2,3,4,5,6,… 1000

You might be like this:

for n in range(1000):
    a=n

At this time, range (1000) generates a list containing 1000 numbers by default, so it takes up a lot of memory.

At this time, you can use the yield combination generator just now to realize it, or you can use xrange (1000) to realize it

Yield Combination:

def foo(num):
    print("starting...")
    while num<10:
        num=num+1
        yield num
for n in foo(0):
    print(n)

Output:

starting...
1
2
3
4
5
6
7
8
9
10

* xrange(1000):

for n in xrange(1000):
    a=n

It should be noted that there is no xrange () in python3. In python3, range () is xrange (). You can check the type of range () in python3. It is a & lt; class’ range ‘& gt; instead of a list. After all, it needs to be optimized.  

Thank you

If you feel helpful, your appreciation is my greatest support!

Read More: