python之生成器

在了解生成器之前,必须要了解一下:列表生成式


生成器:generator

通过列表生成式,列表元素可以一个个推算出来,但当他算出来全部存放着的时候,还是很占用空间。

那我们是否可以在循环过程中不断推算,要用到多少,算到多少,这样就可以节省大量空间。

在Python中,这种一边循环一边计算的机制,叫做生成器。

 

生成器如何定义?

定义方式一:把上面列表生成式的最外层中括号改成小括号:( i * 2 for i in range(10))

#生成器generator

#定义方式一:
a = ( i * 2 for i in range(10))

print(a)    #打印a实际是一个生成器地址
print(a.__next__()) #打印第一个
print(a.__next__()) #打印第二个
for i in a:         #打印接下来的所有
    print(i)

定义方式二:在函数中加入yield关键字。

#方式二:函数
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        #print(b)    #打印每个fib数
        yield b     #写了yield的函数,就是生成器,就不是函数了
        a, b = b, a + b
        n += 1
    return 'done'   #当超过了就会返回这个

a = fib(10) #赋值给a
print(a)    #打印a看一下,实际a是一个生成器(generator)地址

生成器如何使用?

方法一:__next__()方法

#使用方法一:
print(a.__next__())
print(a.__next__())
print(a.__next__()) #打印3次

方法二:循环打印

for i in a: #循环打印出来
    print(i)

方法三:while循环,同时可以抓错误

while True:
    try:
        x = next(a)
        print(x)
    except StopIteration as e:  #当超出的时候抓住错误,并显示生成器的return值
        print(e.value)
        break

注意:1、生成器只有在调用时才会生成相应的数据。

2、生成器只记录当前位置。

3、使用只有一个__next__()方法。

 

生成器的优点?

因为生成器是一次次出来的,所以他的好处就是:

1、可以在中间加入别的东西而不必等全部执行完。2、可以用返回值抓住异常进行处理。

3、还可通过yield实现在单线程的情况下实现并发运算的效果。(下面给个例子)

 

大家体会一下下面这段代码,通过producter函数里面使用consumer生成器,实现做一个吃一个的效果,实现并发运算的效果。

def consumer(name):
    while True:
        food = yield
        print('%s吃了%s号食物'%(name, food))

def producter(name):
    print('%s开始做吃的了'%name)
    c1 = consumer('a')
    c2 = consumer('b')
    c1.__next__()   #第一次要next一下才能走到生成器的yield位置
    c2.__next__()
    for i in range(10):
        print('----------------------')
        print('做好了%s号吃的'%i)
        c1.send(i)    #传给yield
        c2.send(i)

producter('lkh')

这段代码使用send方法,把其他的值传入生成器中的yield,并且赋值给food。同时通过循环,每次发送每次执行consumer生成器,实现模拟了一个并发效果。虽然通过使用函数一样可以实现上面的例子,但当consumer里有不断递进的逻辑的时候,比如有一个递推公式在里面,从而导致每次运算的值不一样的时候,生成器就有很大作用了(主要是为了节省空间而和影响效率,试想,如果一个函数运行要花10分钟算完,那需要一下算一下的体验会远远大于算完再调用的体验)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值