Python Basic knowledge generator

Source: Internet
Author: User
Tags function definition

Generator

With a list generation ( [x * x for x in range(10)] for example), we can create a list directly. However, with memory limitations, the list capacity is certainly limited. Also, creating a list of 1 million elements takes up a lot of storage space, and if we just need to access the first few elements, the vast majority of the space behind it is wasted.

So, if the list element can be calculated according to an algorithm, can we continue to calculate the subsequent elements in the process of the loop? This eliminates the need to create a complete list , saving a lot of space. In Python, this side loop is computed as a mechanism, called the generator: generator .

The generator can only generate data when it is called to record the current location

There are a number of ways to create one generator . The first method is simple, as long as a list of the generated formula is [] changed () to create 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>

The L difference between creating and making is only the outermost and the one, and the g [] () L list other g generator .
We can print out list every element directly, but how do we print out generator every element?
If you want to print out one, you can next() get generator the next return value from the function:

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

As we've said, the generator algorithm is saved, each time it is called, the value of the next(g) next element is computed until the last element is computed, and g no more elements are thrown when the StopIteration error occurs.
Of course, this constant invocation is next(g) really too perverted, the correct way is to use for loops, because it generator is also an iterative object:

>>> g = (x * x for x in range(10))>>> for n in g:...     print(n)...0149162536496481

So, we create a generator post that basically never calls next() , but iterate over it through the for loop and don't need to be concerned about StopIteration the error.
generatorVery powerful. If the calculated algorithm is more complex, and the loop with similar list generation for cannot be implemented, it can also be implemented with functions.
For example, the famous Fibonacci sequence (Fibonacci), except for the first and second numbers, can be summed up by the top two numbers:

1, 1, 2, 3, 5, 8, 13, 21, 34, ...

The Fibonacci sequence is not written in a list, but it is easy to print it out with a function:

def fib(max):    n, a, b = 0, 0, 1    while n < max:        print(b)        a, b = b, a + b        n = n + 1    return ‘done‘

Note that the assignment statement:

a, b = b, a + b

Equivalent:

t = (b, a + b)#  t是一个tuplea = t[0]b = t[1]

However, you do not have to explicitly write out temporary variables t to assign values.
The above function can output the first number of Fibonacci sequences N :

>>> fib(10)11235813213455done

Looking closely, it can be seen that the fib function is actually a calculation rule that defines the Fibonacci sequence, which can be inferred from the first element, and the subsequent arbitrary elements, which are very similar generator .
That is, the above function and generator only one step away. To turn the FIB function into a generator, just print(b) change yield b it to:

def fib(max):    n,a,b = 0,0,1    while n < max:        #print(b)        yield  b        a,b = b,a+b        n += 1    return ‘done‘

This is generator another way of defining it. If a function definition contains a yield keyword, then the function is no longer a normal function, but a generator :

>>> f = fib(6)>>> f<generator object fib at 0x104feaaa0>

What is most difficult to understand here is that it is generator not the same as the execution process of a function. The function is executed sequentially, the statement is encountered return or the last line of the function is returned. The generator function, which executes at each invocation, next() encounters a yield statement return and executes again from the last yield statement returned.

data = fib(10)print(data)print(data.__next__())print(data.__next__())print("干点别的事")print(data.__next__())print(data.__next__())print(data.__next__())print(data.__next__())print(data.__next__())#输出<generator object fib at 0x101be02b0>11干点别的事235813

In fib The example above, we continue to call during the loop yield , and we are constantly interrupted. Of course, you have to set a condition for the loop to exit the loop, or it will produce an infinite sequence.
Similarly, after changing the function generator , we basically never use the next() next return value, but instead use the for loop to iterate:

>>> for n in fib(6):...     print(n)...112358

However for , when called with a loop generator , the generator return value of the statement that is not available is found return . If you want to get the return value, you must catch the Stopiteration error, which is included in the return value StopIteration value :

>>> g = fib(6)>>> while True:...     try:...         x = next(g)...         print(‘g:‘, x)...     except StopIteration as e:...         print(‘Generator return value:‘, e.value)...         break...g: 1g: 1g: 2g: 3g: 5g: 8Generator return value: done

The effect of concurrent operations can also be achieved by yield implementing a single thread

#_*_coding:utf-8_*___author__ = ‘Alex Li‘import timedef consumer(name):    print("%s 准备吃包子啦!" %name)    while True:       baozi = yield       print("包子[%s]来了,被[%s]吃了!" %(baozi,name))def producer(name):    c = consumer(‘A‘)    c2 = consumer(‘B‘)    c.__next__()    c2.__next__()    print("老子开始准备做包子啦!")    for i in range(10):        time.sleep(1)        print("做了2个包子!")        c.send(i)        c2.send(i)producer("alex")

Implementing concurrent parallel operations with generators

Python Basic knowledge generator

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.