python之路-12-生成器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python之路-12-生成器相关的知识,希望对你有一定的参考价值。

12.1列表生成式

示例1
普通做法:
a = [0,1,2,3,4,5,6,7,8,9]

for index,i in enumerate(a):
    a[index] *=2
print(a)

 

列表生成式

b = [i*2 for i in range(10)]
print(b)

 

12.2 生成器

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator

 

12.3列表生成器

b = (i*2 for i in range(10))

总结:列表形式是即使不用元素,也在内存中先生成。生成器保存的是算法,只有在调用时才会生成相应的数据,只记录当前位置,只有一个__next__()方法来获得generator的下一个返回值2.7里是next()

 

12.4函数生成

 

斐波拉契数列:Fibonacci

除第一个和第二个数外,任意一个数都可由前两个数相加得到:1, 1, 2, 3, 5, 8, 13, 21, 34, ...

斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:

 

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        print(b)
        a, b = b, a + b      ##相当于t = (b, a + b) # t是一个tuple    a = t[0]     b = t[1]
        n = n + 1
    return ‘done‘
fib(10)

 

fib函数变成generator,只需要把print(b)改为yield b就可以了:

如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator在每次调用next()的时候执行遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行

 

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

f = fib(5)
print(f.__next__())
print("=============")
print(f.__next__())

for i in f:
    print(i)

 

 

 

 

#!Author:lanhan
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return ‘done‘
print(f.__next__())
print("=============")
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print("====start loop======")
#for i in f:
    #print(i)

 

 

 技术分享图片

 

 

报错的内容是return的内容,异常捕获后就不会报错:

g = fib(6)
while True:
    try:
        x = next(g)
        print(‘g:‘, x)
    except StopIteration as e:
        print(‘Generator return value:‘, e.value)
        break

 

 

 

 

单线程实现并发的过程

#!Author:lanhan
#单线程实现并发的过程
import time
def consumer(name):    ##消费者
    print("%s 准备吃包子啦!" %name)
    while True:
       baozi = yield

       print("包子[%s]来了,被[%s]吃了!" %(baozi,name))

c = consumer("lanhan")
c.__next__()
# b1 = "韭菜馅"
# c.send(b1)           ##调用yield,并且给yield传值
# c.__next__()        ##调用yield
def producer(name):       ###生产者
    c = consumer(‘A‘)
    c2 = consumer(‘B‘)
    c.__next__()
    c2.__next__()
    print("老子开始准备做包子啦!")
    for i in range(10):
        time.sleep(1)
        print("做了1个包子,分两半!")
        c.send(i)
        c2.send(i)
producer("alex")













































































以上是关于python之路-12-生成器的主要内容,如果未能解决你的问题,请参考以下文章

python之路---12 生成器 推导式

python成长之路12——生成器和迭代器

Python学习之路:生成器

Python之路

Python之路----------生成器

Python之路-生成器