Introduction and use of Python Builder

Source: Internet
Author: User

The generator in Python holds the algorithm and calculates the value when it really needs to be computed. It is an inert calculation (lazy evaluation).

There are two ways to create a generator.

The first method: Changing a list-generated [] to () Creates a generator:

>>> L = [x * x for x in range]]>>> l
[0, 1, 4, 9, approx., 81]>>> g = (x * x for x in range (10)) # Note When you change [] to (), instead of generating a tuple, you generate a GENERATOR&G T;>> G<generator Object <genexpr> at 0x1022ef630>

The second way: by using the yield keyword in a function, the function becomes a generator.

After the yield in the function, the execution to yield will stop, when the need to further down the calculation will be counted. So the generator function does not matter if there is an infinite loop, it needs to calculate how much will be counted, do not need to calculate.

def fib ():
A, b = 0, 1
While True:
Yield a
A, B = B, A + b
f = fib ()
Print F, Next (f), Next (f), Next (f)
# <generator Object fib at 0x7f89769d1fa0> 0 1 1

As the above example, the first output F, it is a generator, and then every time next, it executes to yield a.

Of course, in fact, rarely use next (), we directly with the For loop can traverse a generator, in fact, the internal implementation of the For loop is to call next ().

Generators can avoid unnecessary computations, improve performance, and save space for an infinite loop (infinitely large) data structure.

Builder syntax
Generator expression: pass-through list parsing syntax, just replace the list parsing [] with ()
The list of things that the builder expression can do is basically handled, but the list parsing compares the memory when the sequence that needs to be processed is relatively large.

Generator function: If the yield keyword appears in the function, then the function is no longer a normal function, but a generator function.

In Python, yield is such a generator.

The yield generator's operating mechanism:

When you ask the generator to take a number, the generator executes until the yield statement appears, and the generator gives you the yield argument, and the generator does not go down. When you ask him for the next number, he will be from the last state. Start running until the yield statement appears, give you the parameters, and then stop. So repeat until you exit the function.

Use of Yield:

In Python, when you define a function that uses the yield keyword, the function is a generator, and its execution is a lot different from other normal functions, and the function returns an object instead of the return statement you normally use to get the result value. If you want to get a value, you have to call the next () function

The following is a case of Fibonacci retracement:

#coding: Utf8def fib (max): #10    N, a, b = 0, 0, 1 while    n < max: #n <10        #print (b)        yield B        A, B = B, A + b        n + = 1    return f = fib (Ten) for I in F:    print F

From the description of the operating mechanism above, it can be learned that the program runs to yield this line, it will not continue to execute down. Instead, it returns a iterator object that contains the state of all the parameters of the current function . The goal is to be able to access all of the parameter values of the function when it is called for the second time, rather than re-assigning the value at the first visit.

The first time the program is called:

def fib (max): #10    N, a, b = 0, 0, 1 while    n < max: #n <10        #print (b)        yield b   #这时a, b values are 0, 1, of course, the program is also Execute to this point, return        A, B = B, A + b

When the program is called for the second time:

From the front, the first call, a,b=0,0, then, when we call the second time (in fact, is called the first return of the iterator object of the next () method), the program jumps to the yield statement,

Executes a B = b, a+b statement, when the value changes to: A, B = 0, (0+1) = = A, a = 0, 1

The program continues the while loop, and, of course, once again touches the yield a statement, which, like the first time, saves the state of all parameters of the function and returns a iterator object containing the state of those parameters.

Wait for the third call ....

Through the above analysis, you can use the analogy to show the detailed operation of yield!

By using the generator syntax, you can eliminate the tedious code of the write iterator class, such as the example above, which is implemented using an iterative class, with the following code:

#coding: Utf8class Fib:      def __init__ (self, max):          Self.max = max        print Self.max    def __iter__ (self):          self.a = 0          self.b = 1         SELF.N = 0         return self      def next (self):          fib = SELF.N          if fib >= sel F.max:              raise Stopiteration          self.a, self.b = self.b, SELF.A + self.b          SELF.N + = 1        return SELF.A    F = Fib (Ten) for I in F:    print I

Yield and return

In a generator, if there is no return, the default execution is returned to the stopiteration when the function is complete;

If a return is encountered, the Stopiteration abort iteration is thrown directly if the return is executed during execution.

If a value is returned after a return, the error is directly followed, and the generator has no way to return the value using return.

the method supported by the generator (drawing on others ' example, feeling fine)

     Close (...) |      Close (), raise generatorexit inside generator. |   |  Next (...) |      X.next (), the next value, or raise Stopiteration |   |  Send (...) |      Send (ARG), send ' arg ' into generator, |      Return next yielded value or raise stopiteration. |   |  Throw (...) |      Throw (TYP[,VAL[,TB]]), raise exception in generator, |      Return next yielded value or raise stopiteration.

Close ()

Close the generator function manually, and the subsequent call will return the stopiteration exception directly.

#coding: Utf8def fib ():    yield 1    yield 2    yield 3f = fib () print f.next () f.close () print f.next ()

Send ()

The biggest feature of the generator function is the ability to accept an externally passed-in variable and return it based on the contents of the variable.
This is the most difficult place to understand the generator function, and the most important place,

Def gen ():    value=0 while    True:        receive=yield value        if receive== ' e ':            break        value = ' Got:%s '% Receive G=gen () print (G.send (None)) print (     g.send (' aaa ')) Print (G.send (3)) Print (G.send (' e '))

Execution process:

    1. by G.send (None) or Next (g), you can start the generator function and execute to the point where the first yield statement ends. At this point, the yield statement is executed, but receive is not assigned a value. Yield value outputs the initial value 0 Note: You can only send (None) when you start the generator function, and you will get an error message if you try to enter a different value.

    2. by G.send (' AAA '), the AAA is passed in and assigned to receive, then the value of value is computed and returned to the while header, and the yield value statement is stopped. The yield value now outputs "GOT:AAA" and then hangs.

    3. Through G.send (3), the 2nd step is repeated and the result is "Got:3″

    4. When we g.send (' e '), the program executes a break and then rolls out the loop, and finally the entire function is finished, so we get the stopiteration exception.

The results of the final implementation are as follows:

0got:aaagot:3traceback (most recent):  File "1.py", line <module>    print (g.send (' e ')) Stopi Teration

 

Throw ()

Used to feed an exception to the generator function, which can end a system-defined exception, or a custom exception.
Throw () runs directly out of the exception and ends the program, either consumes a yield, or goes directly to the end of the program without the next yield.

Def Gen (): While    True:         try:            yield ' normal value '            yield ' normal value 2 '            print (' here ')        except ValueError:            print (' We got valueerror here ')        except TypeError: Break            G=gen () print (Next (g)) print ( G.throw (ValueError)) print (Next (g)) print (G.throw (TypeError))

Execution process:

    1. Print (Next (g)): The normal value is output and stays before yield ' normal value 2 '.

    2. Because G.throw (valueerror) is executed, all subsequent try statements are skipped, which means that the yield ' normal value 2 ' will not be executed, and then go into the except statement and print out the We got valueerror here. It then enters the while statement part again, consumes a yield, and outputs the normal value.

    3. Print (Next (g)) executes the yield ' normal value 2 ' statement and stays where it was after the statement was executed.

    4. G.throw (TypeError): Will jump out of the try statement so that print (' here ') will not be executed, then execute the break statement, jump out of the while loop, and then reach the end of the program, so run out of the stopiteration exception.

  

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.