Python functions and common modules-generators

Source: Internet
Author: User
Tags generator

Generator

What is a list-generated formula?

This is the basic list

>>> a = [1, 2, 3]>>> a[1, 2, 3]

Can also be expressed in a different way

>>> [ i*2 for i in range(10)][0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

But what's the difference between these two lists?

The first list of lists has been written dead, cannot be changed, and the second list is dynamic when it is produced, and the second method can be realized using the following code.

>>> a = []>>> for i in range(10):...     a.append(i*2)...>>> a[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

Well! The effect is the same as the result of the second writing, so the second method of writing, in fact 列表生成式 , is that the main purpose is to make the code a little bit more succinct.

Generator

Through list generation, we can create a list directly, but by the memory limit, the list is limited in capacity, and by creating a list of 100 specimens elements, not only taking up a large storage space, we actually only have access to the first few elements of this list, and then most of the elements occupy the space, Not in vain?!

So, if the list element can be inferred from a certain algorithm, then can we in the cycle of the process, constantly calculate the back of the elements?! There is no need to create a complete list, which saves a lot of storage space, and in Python, this one-by-one computing system is called生成器(generator)

In version python2.x, range(10) all the elements have been prepared, placed in memory, and in Python3 is not ready, so you can save some memory space, as to why?!!!!!!! The details are not to say that it is only necessary to know first.

# Python2.x>>> range(10)[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# Python3 >>> range(10)range(0, 10)

Is it possible to adjust the required elements before generating the corresponding elements?! It's actually possible, and we're going to do a simple generator with a "rule".

This is 列表生成式 ↓↓↓.

>>> [ i * 2 for i in range(10) ][0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

As long as 中括號 小括號 you change it, you can become生成器

>>> ( i*2 for i in range(10) )<generator object <genexpr> at 0x103cd8910>

This is one 生成器 of the codes above, which is multiplied by 2 per cycle.

And then we'll try to verify why it's 生成器 better 列表生成式 to save space.

First we observe, using the results generated by the list, the following code, one by one, is observed 列表生成式 in the Python3.

    • [ i*2 for i in range(100) ]
    • [ i*2 for i in range(1000) ]
    • [ i*2 for i in range(10000) ]
    • [ i*2 for i in range(100000) ]
    • [ i*2 for i in range(1000000) ]
    • [ i*2 for i in range(10000000) ]=-my pen is going to be slow.
    • [ i*2 for i in range(100000000) ]

range(10000000)It's going to slow down, because when the list is generated, all the elements in the list are printed at once, and when your machine's memory space is not enough, the problem is that it happens.

To observe the value of 列表生成式a

>>> a = [ i*2 for i in range(10000000) ]>>> a...(略), 153018, 153020, 153022, 153024, 153026, 153028, 153030, 153032, 153034, 153036, 153038, 153040, 153042, 153044, 153046, 153048, 153050, 153052, 153054, 153056, 153058, 153060, 153062, 153064, 153066, 153068, 153070, 153072, 153074, 153076, 153078, 153080, 153082, 153084, 153086, 153088, 153090, 153092, 153094, 153096, 153098, 153100, 153102, 153104, 153106, 153108, 153110, 153112, 153114, 153116, 153118, 153120, 153122, 153124, 153126, 153128, 153130, 153132, 153134, 153136, 153138, 153140, 153142, 153144, 153146, 153148, 153150, 15^CTraceback (most recent call last):  File "<stdin>", line 1, in <module>KeyboardInterrupt>>> >>> # 實際去訪問a列表中的第10000個元素>>> a[10000]20000>>>

And to observe the 生成器 value ofb

>>> b = ( i*2 for i in range(10000000) )>>> b<generator object <genexpr> at 0x1042c80a0>>>>  # ↑實際上會發現根本沒有生成任何元素,只是返回了一個記憶體位址而已 >>>>>>>>> # ↓直接去循環這個生成式,這樣才會去調用它,才會生成對應的元素>>> for i in b:...     print(i)...(略)9924099242992449924699248^C99260Traceback (most recent call last):  File "<stdin>", line 2, in <module>KeyboardInterrupt>>>>>> # ↓同樣去用列表的方式去訪問它>>> c[10000]Traceback (most recent call last):  File "<stdin>", line 1, in <module>TypeError: ‘generator‘ object is not subscriptable>>>

It is learned from the above observation that 生成器 it is to adjust the time to produce integration processes, so it does not support the form of a list of slices.

So there are other ways besides the for loop to get the numbers?! There is currently only one method callednext

    • Usage of python2.x:next()
    • Usage of Python3:__next__()

So what if you want to visit someone else?

>>> # 請看上面最後停止的數字是 99260>>> b.__next__()99262>>> b.__next__()99264>>> b.__next__()99266

生成器是不能往前調用的That... How does the generator save memory? Generator 只記得當前的位置 ,
So when we create a generator, we basically don't adjust __next__() it, but we use it for the loop, and we don't need to be concerned about stopiteration mistakes.

If the calculated algorithm is more complex, with a type-like list generated for the loop can not be realized, but also with the function, for example, the famous Fibonacci columns (Fibonacci), in addition to the first and second numbers, any number can be added by the preceding two numbers:

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

The Fibonacci number column (Fibonacci) is not written in list generation, but it is easy to print it out with a function

#!/usr/bin/env python3# -*- coding:utf-8 -*-def fib(max):    n, a, b = 0, 0, 1    while n < max:        print(b)        a, b = b, a + b        # a = b     => a = 1, b = 2 ; a = b,  a = 2        # b = a + b => b = 2 + 2 = 4        n = n + 1    return ‘done‘print(fib(10))---------------執行結果---------------11235813213455doneProcess finished with exit code 0

Note that the value of the language sentence

a, b = b , a + b

It's actually a

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

Please see example

>>> a, b = 1, 2>>> t = ( b, a + b )>>> t(2, 3)>>> print(t[0])2>>> print(t[1])3>>>

But it is not necessary to write out the temporary changes t to the value.

After a few observations, it is not difficult to see that the FIB function is actually defining the Fibonacci calculation rules, you can start from the first element, calculate the back of arbitrary elements, this kind of logically is very similar generator .

That is to say, the above function and generator only one step, to change the FIB function into generator, only need to change to print(b) yield b be able to.

!/usr/bin/env python3# -*- coding:utf-8 -*-def fib(max):    n, a, b = 0, 0, 1    while n < max:        # print(b)        yield b        a, b = b, a + b        n = n + 1    return ‘done‘# fib(10)print(fib(10))---------------執行結果---------------<generator object fib at 0x10a0c5f10>Process finished with exit code 0

Yes! It becomes 生成器 .

This is another way of defining generator, if a function definition contains yield This key, then this function is not an ordinary function, but rather a one.generator

So let's use __next__() this method to adjust this generator as we said before.

#!/usr/bin/env python3# -*- coding:utf-8 -*-def fib(max):    n, a, b = 0, 0, 1    while n < max:        # print(b)        yield b        a, b = b, a + b        n = n + 1    # return ‘done‘f = fib(100)print(f.__next__())print(f.__next__())print(f.__next__())---------------執行結果---------------112Process finished with exit code 0

yieldThis allows us to temporarily leave the current function and jump out of the way to do something else.

#!/usr/bin/env python3# -*- coding:utf-8 -*-def fib(max):    n, a, b = 0, 0, 1    while n < max:        # print(b)        yield b        a, b = b, a + b        n = n + 1    # return ‘done‘f = fib(100)print(f.__next__())print("====exit function====")print(f.__next__())print(f.__next__())---------------執行結果---------------1====exit function====12Process finished with exit code 0

The hardest thing to understand here is that the flow of generator and functions is different, the function is executed sequentially, return語句 or the last line of correspondence is returned. The function that becomes a generator is executed each time it is adjusted, encounters a return, and then carries on the line from __next__() yield語句 The last yield language that was returned.

#!/usr/bin/env python3# -*- coding:utf-8 -*-def fib(max):    n, a, b = 0, 0, 1    while n < max:        # print(b)        yield b        a, b = b, a + b        n = n + 1    # return ‘done‘f = fib(10)print(f.__next__())print("====exit function====")print(f.__next__())print(f.__next__())print("====start loop====")for i in f:    print(i)    ---------------執行結果---------------1====exit function====12====start loop====35813213455Process finished with exit code 0

In the above Fib example, we constantly adjust the yield in the loop, and then we will keep going, and of course we have to set a condition for the loop to exit the loop, or it will produce an unlimited list.

In the same way, after changing the function to generator, we basically never use it __next__() to get a return value, but instead use the for loop directly to iterate

This time to take out the comments in the return language, to observe the use for the loop, will print it?

#!/usr/bin/env python3# -*- coding:utf-8 -*-def fib(max):    n, a, b = 0, 0, 1    while n < max:        # print(b)        yield b        a, b = b, a + b        n = n + 1    return ‘done‘f = fib(10)print(f.__next__())print("====exit function====")print(f.__next__())print(f.__next__())print("====start loop====")for i in f:    print(i)    ---------------執行結果---------------1====exit function====12====start loop====35813213455Process finished with exit code 0

There is no print out Yes, why?! No, let's not use the For loop, and print it directly with print.

#!/usr/bin/env python3# -*- coding:utf-8 -*-def fib(max):    n, a, b = 0, 0, 1    while n < max:        # print(b)        yield b        a, b = b, a + b        n = n + 1    return ‘done‘f = fib(10)print(f.__next__())print("====exit function====")print(f.__next__())print(f.__next__())print(f.__next__())print(f.__next__())print(f.__next__())print(f.__next__())print(f.__next__())print(f.__next__())print(f.__next__())print(f.__next__())---------------執行結果---------------Traceback (most recent call last):  File "/Pythone/project/fibonacci_basic.py", line 27, in <module>    print(f.__next__())StopIteration: done1====exit function====1235813213455Process finished with exit code 1

As long as you use this method to get a __next__() value, if you take the last line, no value can be taken, it will be thrown out StopIteration: done of such an abnormal.

If you want to get the return value, you have to catch stopiteration wrong, and the return value is contained in the value of stopiteration

#!/usr/bin/env python3# -*- coding:utf-8 -*-def fib(max):    n, a, b = 0, 0, 1    while n < max:        # print(b)        yield b        a, b = b, a + b        n = n + 1    return ‘出現異常,return想打印什麼就打印什麼‘f = fib(10)while True:    try:        x = next(f)        print(‘f:‘, x)    except StopIteration as e:        print("Generator return value:", e.value)        breakprint("====start loop====")for i in f:    print(i)---------------執行結果---------------f: 1f: 1f: 2f: 3f: 5f: 8f: 13f: 21f: 34f: 55Generator return value: 出現異常,return想打印什麼就打印什麼====start loop====Process finished with exit code 0    

The above code, which has not been called a function, is a generator, because in the code there is already a yield phrase, and the function of return here is an abnormal time, and the message that is printed.

Python functions and common modules-generators

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.