Python入门(十二)——生成器


需要明确,生成器是迭代器,具备可迭代功能,但是反之不成立。

1 创建生成器

1.1 列表生成式

可以用[ ] 里面加入表达式和函数的形式生成一个列表

a = [x for x in range(9)]
print(type(a))
a = [x*x for x in range(9)]
print(a)

def f(n):
    return n*n*n
print([f(x) for x in range(8)])

在这里插入图片描述

1.2 用小括号()生成生成器

生成器比传统的列表节省省空间,是一种用的时候才会产生占用内存数据的懒工厂方式

'''生成器小括号产生方式'''
a = (x for x in range(9))
print(type(a))
a = (x*x for x in range(9))
for i in a:
    print(i, end='\t')
print()

def f(n):
    return n*n*n
a= (f(x) for x in range(8))
for i in a:
    print(i, end='\t')

在这里插入图片描述

1.3 yield创建生成器函数

yiel是一个语法糖,替换return语句之后实现返回功能,内部实现迭代器协议,同时保持状态可以挂起。

'''菲波纳契数列--生成器版'''
def fibonacci(max):
    n, a, b = 0, 0, 1
    while n <= max:
        a, b = b, a+b
        yield b
        n += 1

for k in fibonacci(5):
    print(k, end='\t')

在这里插入图片描述
代码解释,k在执行for语句得时候相当于每一次取到next()迭代后的值,而每一次都是直行道yield返回的值即为迭代后的值,相当于执行以下代码:

'''菲波纳契数列--生成器版'''
def fibonacci(max):
    n, a, b = 0, 0, 1
    while n <= max:
        a, b = b, a+b
        yield b
        n += 1
f = fibonacci(5)
k = next(f)
print(k)
k = next(f)
print(k)
k = next(f)
print(k)
k = next(f)
print(k)
k = next(f)
print(k)
k = next(f)
print(k)
k = next(f)
print(k)

在这里插入图片描述
StopIteration:在函数执行结束(正常结束,或者遇到return)之后,没有遇到yield就会抛出该错误。相当于某一次next()方法没有遇到yield执行完函数即抛出该错误。

另外,遇到了StopIteration错误之后for进行自动处理了。

1.4 理解两次调用生成器函数

'''理解两次调用生成器函数产生的效果:相当于两个对象,用类的思想很好理解'''
def fibonacci(max):
    n, a, b = 0, 0, 1
    while n <= max:
        a, b = b, a+b
        yield b
        n += 1
f = fibonacci(5)
f2 = fibonacci(4)

for k in f:
    print('f1:', k, end='\t')
    for j in f2:
        print('f2:', j, end='\t')

在这里插入图片描述

2 .send() 方法理解和应用

当调用send的时候将执行两个步骤:

  • 传参给yield语句(整体)
  • next()
    因为第一次调用没有遇到yield,因此第一次send(None),否则会报错
'''初级测试send()'''
def foo(n):
    print('运行开始')
    while n > 0:
        count = (yield 7) * n
        print(count, n)
        n -= 1
    return 1

f = foo(3)
f.send(None)
f.send(9)
f.send(12)
f.send(22)
f.send(32)

在这里插入图片描述

3 生成器函数实现协程应用

所谓协同程序也就是是可以挂起,恢复,有多个进入点。其实说白了,也就是说多个函数可以同时进行,可以相互之间发送消息等。

#基于yield实现异步
import time
def consumer():
    '''任务1:接收数据,处理数据'''
    while True:
        x=yield
        # print(x, end='\t')
        time.sleep(0.2)
        print(x)

def producer():
    '''任务2:生产数据'''
    g=consumer()
    next(g)
    for i in range(100):
        g.send(i)

producer()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值