Python Builder (Generator) detailed _python

Source: Internet
Author: User
Tags function definition generator stdin

With a list generation, we can create a list directly. However, the list capacity is certainly limited by the memory limit. And, creating a list of 1 million elements, not only takes up a lot of storage space, but if we just need to access the first few elements, the space behind most of the elements is wasted.

So if the list element can be calculated according to some algorithm, can we continue to calculate the subsequent elements in the process of the loop? This eliminates the need to create a complete list, which saves a lot of space. In Python, this loop-side computing mechanism is called the Generator (generator).

Simple generator

There are a number of ways to create a generator. The first method is simple, as long as you change a list-generated [] to (), you create a generator:

Copy Code code as follows:

>>> 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 0x104feab40>

The difference between creating L and G is only the outermost [] and (), L is a list, and G is a generator.
We can print out every element of the list directly, but how do we print out every element of the generator?

If you want to print one, you can pass the generator Next () method:

Copy Code code as follows:

>>> G.next ()
0
>>> G.next ()
1
>>> G.next ()
4
>>> G.next ()
9
>>> G.next ()
16
>>> G.next ()
25
>>> G.next ()
36
>>> G.next ()
49
>>> G.next ()
64
>>> G.next ()
81
>>> G.next ()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Stopiteration

As we've said, generator saves the algorithm, and each time you call next, the value of the next element is computed until the last element is computed, and no more elements are thrown when the stopiteration error is raised.

Of course, this constant call to the next () method is really sick, and the correct way is to use a For loop because generator is also an iterative object:

Copy Code code as follows:

>>> g = (x * x for x in range (10))
>>> for N in G:
... print n
...
0
1
4
9
16
25
36
49
64
81

So, after we create a generator, we basically never call the next () method, but iterate over it through a for loop.

Generator with yield statement

Careful observation, we can see that the FIB function is actually defined the Fibonacci sequence of the calculation rules, you can start from the first element to calculate the subsequent arbitrary elements, this logic is very similar to generator.

In other words, the above function and generator are only one step away. To turn the FIB function into a generator, you simply change print B to yield B:

Copy Code code as follows:

def fib (max):
N, a, b = 0, 0, 1
While n < max:
Yield b
A, B = B, A + b
n = n + 1

This is another way to define generator. If a function definition contains the yield keyword, then the function is no longer a normal function, but a generator:
Copy Code code as follows:

>>> FIB (6)
<generator Object fib at 0x104feaaa0>

The most difficult thing to understand here is that the generator and function are not performing the same process. The function is executed sequentially, and the return statement is encountered or the last line of function statement is returned. The function that becomes generator, executes at each call next (), encounters a yield statement return, and executes again from the last yield statement that was returned.

To give a simple example, define a generator, and then return the number 1,3,5:

Copy Code code as follows:

>>> def Odd ():
... print ' Step 1 '
... yield 1
... print ' Step 2 '
... yield 3
... print ' Step 3 '
... yield 5
...
>>> o = Odd ()
>>> O.next ()
Step 1
1
>>> O.next ()
Step 2
3
>>> O.next ()
Step 3
5
>>> O.next ()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Stopiteration

As you can see, odd is not a normal function, but a generator, in the execution process, encountered yield interrupted, the next time to continue execution. After performing 3 yield, no yield can be executed, so the 4th call to Next () is an error.

Back to Fib's example, we constantly call yield during the loop, and we interrupt. Of course, set a condition to the loop to exit the loop, or it will produce an infinite series out.

Again, after changing the function to generator, we basically never invoke it with next (), but instead use the For loop to iterate:

Copy Code code as follows:

>>> for N in fib (6):
... print n
...
1
1
2
3
5
8

Enhanced Generators

In python2.5, some of the enhanced features are added to the builder, so the next () value can be returned to the generator [Send ()], throw an exception in the generator, and require the generator to exit [Close ()]

Copy Code code as follows:

Def gen (x):
Count = X
While True:
val = (yield count)
If Val is not None:
Count = Val
Else
Count + 1

f = Gen (5)
Print F.next ()
Print F.next ()
Print F.next ()
print ' ==================== '
Print F.send (9) #发送数字9给生成器
Print F.next ()
Print F.next ()


Output
Copy Code code as follows:

5
6
7
====================
9
10
11

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.