Starting from python's yield, pythonyield
Some time ago, when I was reading the source code of the wiki module in trac, I found that yiled is used in many places,
It seems that yield is used to replace return in the place where a value needs to be returned,
I am not very familiar with its usage, so I will study it carefully.
A function that uses the yiled keyword is no longer a common function, but a generator function ),
When a function is called, an iterator is returned ).
So the concepts of the iterator and generator are explained below.
I. Iterator)
Writing that the iterator is an object that implements the iterator protocol,
Generally, you need to implement the following two methods:
1) next Method
Returns the next element of the container.
2) _ iter _ Method
Return iterator itself
We may not be familiar with the for language. We often need to traverse some container objects to use the for Loop:
Python code
- L = [0, 1, 2, 3, 4, 5, 6]
- For I in l:
- Print I
L is a list object. During the running of this for-in code, it actually calls the l _ iter _ () function, returns an iterator object that implements _ next _ () or next () (python of different versions may be different. The version I used in the experiment is 2.6.2, the next element is obtained through next for each loop.
Of course, we do not need to calculate all the elements first and put them in a list or loop in other container classes, which is a waste of space.
We can directly create an iterator of our own.
Python code
- #-*-Coding: UTF-8 -*-
- '''
- Class Fib:
- ''''' An iterator that can generate the Fibonacci series '''
- Def _ init _ (self, max ):
- Self. max = max
- Def _ iter _ (self ):
- Self. a = 0
- Self. B = 1
- Return self
- Def next (self ):
- Fib = self.
- If fib> self. max:
- Raise StopIteration
- Self. a, self. B = self. B, self. a + self. B
- Return fib
After defining the Fibonacci iterator, we can use it.
Python code
- From maid import Fib
- For n in Fib (1000 ):
- Print n
When Fib (1000) is called, an iterator object is generated, and each loop calls next to get the next value.
So we can see that the iterator has a very core thing that is in the loop. The iterator can remember the previous state.
Ii. Generator
As we mentioned above, any function that uses the yield keyword is no longer a common function. Let's look at the instance. This is easier to understand.
Python code
- Def fib (max ):
- A, B = 0, 1
- While a <max:
- Yield
- A, B = B, a + B
Here, a few simple lines of code implement the functions implemented by a lot of code in the previous iterator class.
The usage is similar to the above:
Python code
- From maid import fib
- For n in fib (1000 ):
- Print n
The citation fib function uses yield, so it is a generator function. When we call fib (1000), it actually returns an iterator, this iterator can control the running of generator functions.
We control the running of the generator function of fib through the action of the returned iterator.
Every time the next function of the iterator is called, when the generator function runs to yield, the value after yield is returned and paused at this place, all the statuses will be kept, wait until the next function is called or an exception loop is triggered to exit.
So the concept of generator is very simple.
Iii. Summary
1. the for-in statement operates on an iterator object at the underlying layer.
2. A function that uses the yield keyword is a generator function. When called, an iterator that can control its own running is generated.
Usage of yield in python
Yield is used to save the execution status of the current program.
When you use a for loop, it is calculated every time an element is retrieved.
The yield function is called generator. Like iterator, yield does not calculate all elements at a time, but only one operation at a time, which saves a lot of space. Generator requires the last calculation result for each calculation, so yield is used. Otherwise, the result of the previous calculation will be lost after a return operation.
Therefore, it is totally incorrect to save the list.
In python, how does return and yield work? What are the differences between the two?
I often see that there are not many Chinese interpretations that can be found when others use or discuss the yield syntax. Today I am determined to fix yield and paste my understanding here.
Before yield: iterator)
Yield: generator (constructor) found)
Use yield: recursive call
1. iterator
The simplest example of the stack generator should be the array subscript. See the following c ++ code:
Int array [10];
For (int I = 0; I <10; I ++)
Printf ("% d", array [I]);
The stacked generator works in a container (array [10]), which extracts values from the container in a certain order (I ++) (array [I]) and perform operations (printf ("% d", array [I]).
The above code is translated into python:
Array = [I for I in range (10)]
For I in array:
Print I,
For I in array )? First, array is a container as a list, and secondly, the list built-in type has the default next action. What is the secret acquired after python finds that is not seen by everyone: take out the array, which is the container's heap generator. next from the inside, give the value to I for processing by the for loop entity. for, print the value.
The problem now is that data can be stacked in containers. Can code be used?
Why not? The dishes can be used to store dishes. Won't the wk think of using nt to store dishes? Of course, our yield won't be so yellow + bt.
2. constructor
How to change a function into a constructor? You just need yield in the function body!
Def gen ():
Print 'enter'
Yield 1
Print 'Next'
Yield 2
Print 'Next again'
For I in gen ():
Print I
Everybody! In python, yield appears in the gen function, and you can use next. The problem is, how to play next to the Code container?
When I get the iterator from the container, it does not have anything. It is at the container entrance. For arrays, it is the place where the subscript is-1. For functions, it is the function entry, however, if everything is ready, it will be less than next.
Start for I in g, next let itreator crawl to the place where the yield statement exists and return the value,
Next, go to the place where the next yield statement exists and return the values until the function returns (the end of the container ).
The output of the above Code is:
Enter
1
Next
2
Next again
If you do not see it, please do not read it down to avoid yield fixing it.
3. Use yield
Yield's code stacks not only interrupt function execution, but also write down the data at the breakpoint. next time the next book is connected, this is exactly what recursive functions need.
For example, traverse a binary tree in the middle order:
(It should have been written by David Mertz)
Def inorder (t ):
If t:
For x in inorder (t. left ):
Yield x
Yield t. label
For x in inorder (t. right ):
Yield x
For n in inorder (tree)
Print n
Of course, yield's ability to code next can also be used in other aspects, and it is found that the case is being posted... the remaining full text>