Python3 --- 生成器

1、什么是生成器

通过列表生成式,我们可以直接创建一个列表,但是,这样创建的列表存在内存限制,代码如下:

a = [x for x in range(10)]
print(a)

结果是:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

那么当我的rang()的值是10万、100万。。。1亿啦,这样会创建列表,这样的列表会占用大量的内存,甚至导致内存溢出,程序挂掉等等问题,为了解决这样的问题,Python推出了生成器,即当我创建列表时,只是在内存中划分一块较小的空间用于存储列表生成式,而不生成列表,当需要使用列表中的值的时候才创建列表中的值,这就是生成器。


2、生成器的创建方式一

# 列表生成式
a = [x for x in range(10)]
print(a)

print("="*50)

# 生成器
b = (x for x in range(10))
print(b)
print(next(b))
print(next(b))
print(next(b))
print(next(b))
生成器的第一种创建方式是将生成式的[]变成()即可

生成器保存的是算法,每次调用next(b),就计算出b的下一个元素的值,直到计算到最后一个元素,如果没有更多元素时,抛出Stoplteration的异常。一般使用的是for循环来迭代生成器,并且不需要关心Stoplteration异常


3、生成器的创建方式二

如果列表值不是通过生成式生成的,而是通过一定的算法,通过第一次执行时生成的结果作为依据生成后续执行的结果,如斐波拉契数列,这样的可以通过生成器方式二创建,代码如下:

def createFib(num):
    print("----start----")
    a,b = 0,1
    for i in range(num):
        yield b
        a,b = b,a+b
    print("----end----")
    return "end";

fib = createFib(5)
print(next(fib))
print(next(fib))
print(next(fib))
print(next(fib))
print(next(fib))

结果是:

----start----
1
1
2
3
5

(1)从结果可以看出,----end----没有打印,这是因为执行到yield b时进行了特殊的处理,程序停留在了yield b,当执行next时,才会继续向下执行,使用for则不会出现这种情况,代码如下:

for i in createFib(5):
    print(i)
(2)next(fib)和fib.__next()__等价

(3)无法获取return的返回值,如果想要拿到返回值,必须捕获Stoplteration错误,返回值包含在Stoplteration的value中

while True:
    try:
        x = next(fib)
        print("value:%d"%x)
    except StopIteration as e :
        print("生成器返回值:%s"%e.value)
        break


4、生成器中的send

def fun():
    i = 0
    while i<5:
        temp = yield i
        print(temp)
        i += 1

f = fun()
next(f)
next(f)

结果是:

0
None
1

当第一次执行next(f)时,运行到yield i,然后停止,等待下一次next,当第二次执行next(f)时,此时进行temp的赋值操作,但是现在没有进行值赋值给temp,所以输出的print(temp)为None,那么如何给temp赋值啦?可以通过send进行赋值操作,如下:

def fun():
    i = 0
    while i<5:
        temp = yield i
        print(temp)
        i += 1

f = fun()
print(f.__next__())
print(f.send('为temp赋值成功'))
print(f.__next__())

5、多任务

def test1():
    while True:
        print("---1---")
        yield None

def test2():
    while True:
        print("---2---")
        yield None
        
t1 = test1()
t2 = test2()
while True:
    t1.__next__()
    t2.__next__()
这种多任务方式称为协程多任务,多任务分为协程、进程、线程


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值