Detailed Python generators

1. The definition of generator

In Python, while the side calculation cycle mechanism, known as a generator: generator.

 

2. Why should Builder

A list of all data in memory, if there is massive data then will be very memory consumption.

Such as: only need to access the first few elements behind the elements that the vast majority of occupied space are wasted.

If the list elements extrapolated according to some algorithm, then we can continue to calculate the subsequent elements in the course of the cycle, so you do not create a complete list, thus saving a lot of space.

To put it simply: I want to get huge data, and want it to take up less space, then use a generator!

 

3. How to create generator

The first method is very simple, as long as a list generation type of []change (), creates a generator:

 

>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>

 Creating Land gdiffer only in the outermost layer []and (), La list, and ga generator.

 

Second method, if a function contains yieldthe keyword, then this function is no longer an ordinary function, but a generator. Call function is to create a generator (generator) objects.

 

4. The generator works

Key (1) generator (Generator) capable of iteration is that it has a next () method,

  Working principle is by repeatedly calling the next () method until you catch an exception.

(2) yield no longer function with a common function, but a generator generator.

  Available next () call to generate object values. next two ways t .__ next __ () | next (t).

  Available for loop acquires a return value (Each time, which takes a value generator)

  (Not substantially used next()to obtain a return value is, but the use of direct forcycle iterations).

(3) yield the equivalent return to return a value, and remember this return position, the next iteration, the code is executed from the next statement of yield.

(4) .send () and next () the same, so that the generator can continue to go one step further (next encounter yield stop) down, but send () can pass a value that as a result of the overall yield of expression

  - in other words, you can send a force to modify the value of the expression yield. Such as a yield function assignment, a = yield 5, this first iteration will return to 5, a not yet assigned. Second iteration, using .send (10), then, is forced to modify the yield 5 expression is 10, originally 5, then a = 10

 

Yield return process value under feelings ( concern: where each stop, the next time they start where ) and send () parameter passing communication process,

Thinking about how None is generated (first value:. Yield returns i value 0, stopped at the yield i, temp did not assign a value to a second value, beginning in print, temp has not been assigned, so the print None, i is incremented by 1, while continuing determination, the yield of the return value of i 1, stopped at yield i):

 

 

 

Well, he did not talk much, Cuihua, on chestnuts:

 

 1 #encoding:UTF-8  
 2 def yield_test(n):  
 3     for i in range(n):  
 4         yield call(i)  
 5         print("i=",i)      
 6     print("Done.")  
 7   
 8 def call(i):  
 9     return i*2  
10   
11 for i in yield_test(5):  
12     print(i,",")

 

  result:

 

>>>   
0 ,  
i= 0  
2 ,  
i= 1  
4 ,  
i= 2  
6 ,  
i= 3  
8 ,  
i= 4  
Done.
>>>

 

 The key to understanding is that: when the next iteration, the code is executed from the next statement of yield.

 

 to sum up:

What is a generator?

Builder just to save a set of algorithms to generate value, and did not let this algorithm will now begin, but when I tune it, and when it starts to calculate a new value, and return to you.

 

 

Exercises:

 

def count_down(n):
    while n >= 0:
        newn = yield n
        print('newn', newn)
        if newn:
            print('if')
            n = newn
            print('n =', n)
        else:
            n -= 1


cd = count_down(5)
for i in cd:
    print(i, ',')
    if i == 5:
        cd.send(3)

 

 

result:

 

Note: xx = yield yy
Abstract: The effect of send () is to assign a value of xx (send parameter) is sent, and then to allow the next generation performs the yield ..

Use send (params) different situation.
Note: If a producer does not start, it must be necessary to start the generator () before use send, and the method may be initiated generator.next () or generator.send (None) to perform at first a yield, after you can use the send (params) continued the incoming values.
If it is started, then send (params) role is to give xx assigned value (the parameter send) to send, and then let the builder perform the next yield.

Why send (None), is also well understood, because the generator has not come to the first yield statement, if we happen a true value, then there is no one to "receive" it. Once the generator started, it objects to accept (left or left of the value xx = number received),
then you can use the send (params) continued the incoming values.

▲ Note that each of the send () will run to the yield statement, but does not perform the assignment, there will only be a return value, equivalent to return after the exit function, so the assignment after the return value will not be executed.

 

Published 43 original articles · won praise 28 · views 40000 +

Guess you like

Origin blog.csdn.net/u013380694/article/details/101285849