First of all, if you do not have a preliminary understanding of yield, then you first think of yield as a "return", this is intuitive, it is first a return, what is the meaning of the ordinary return, that is, to return to a certain value in the program, after the return of the program will no longer run down. Look at it as a return and then look at it as a generator (generator) part (with the field of the function is the real iterator), well, if you don't understand these words, then first look at the field as a return, and then look directly at the following program, you will understand the full meaning of the field:
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 simple lines of code to let you understand what is yield, the output of the code this:
starting...
4
********************
res: None
4
I directly explain the order in which the code runs, which is equivalent to single-step debugging of the code:
1. After the program starts executing, because there is a yield keyword in the foo function, the foo function will not really execute, but first get a generator g (equivalent to an object)
2. Until the next method is called, the foo function formally begins to execute, first execute the print method in the foo function, then enter the while loop
3. The program encounters the yield keyword, and then think of yield as return, return a 4, the program stops, and does not perform the assignment to the res operation, at this time, next (g) statement execution is complete, so the output of the first two lines (the first while the results of the above print, the second is the result of the return out of the results) is the implementation of the print(next(g)).
4. The program executes print("*"*20), which outputs 20 *'s
5. and began to execute the following print (next (g)), this time and the above one is almost the same, but the difference is that this time from the next program just stopped the place to start the implementation, that is, to perform the assignment of res operation, this time to pay attention to, this time the assignment of the operation of the right side is not the value of the (because just now that is return out and did not pass parameters to the left side of the assignment operation), so this time the res assignment is None, so then the following output is res:None, the
6. The program will continue to execute in the while, and once again encountered yield, this time the same return out of 4, and then the program stops, print function output of 4 is this return out of 4.
Here you may understand the relationship between yield and return and the difference, with yield function is a generator, not a function, this generator has a function is next function, next is equivalent to the "next step" to generate which number, this time the next start place is Then the next stop where the last execution, so call next, the generator will not start from the beginning of the implementation of the foo function, just followed by the last step to stop the beginning of the place, and then encountered after the field, return the number to be generated, the end of this step.
****************************************************************************************************************************************
def foo(): print("starting...") while True: res = yield 4 print("res:",res) g = foo() print(next(g)) print("*"*20) print((7))
Look at another example of this generator's send function, this one replaces the last line of the one above and outputs the result:
starting...
4
********************
res: 7
4
first roughly the concept of send function: at this point you should notice that the purple word above, and above the value of the res why None, this became 7, in the end, why, this is because, send is to send a parameter to the res, because of the above, return time, and did not assign the value of 4 to the res, the next time the implementation of the res, had to be assigned to None. continue to perform the assignment operation, had to be assigned to None, and if you use send, then, the beginning of the implementation of the first time, followed by the last time (return 4 after the implementation of the first 7 assigned to the res, and then perform the role of next, meet the next back of the yield, return the results after the end.
5. Program execution (7), the program will continue down the line from the yield keyword, send will assign the value of 7 to the res variable
6. Since the send method contains the next() method, the program will continue to run down the print method and then enter the while loop again.
7. Program execution again encountered yield keyword, yield will return the value of the latter, the program again suspended until the next method or send method is called again.
That's the end of it, and as a side note, the reason why this generator is used is because it would take up a lot more space if you used a List, for example, to take 0,1,2,3,4,5,6 ........... .1000
You might:
for n in range(1000): a=n
At this point, range(1000) generates a list of 1000 numbers by default, so it takes up a lot of memory.
At this point you can use the combination of the yields you just used as a generator to implement it, or you can use xrange(1000) as a generator to implement it
Yield combinations:
def foo(num): print("starting...") while num<10: num=num+1 yield num for n in foo(0): print(n)
Output:
starting...12345678910
xrange(1000):
for n in xrange(1000): a=n
One of the things to note is that there is no longer xrange() in python3, in python3, range() is xrange(), you can look at the type of range() in python3, it's already a <class 'range'> and not a list, after all, this needs to be optimized of it.
summarize
That's all for this post, I hope it was helpful and I hope you'll check back for more from me!