生成器

生成器(generator)

什么是生成器?

  • 简单的来说:一边运行一边生产数据的方式
  • 生成器是一类特殊的迭代器
  • 特点:数据真正需要的时候再生产,而不是先生成N个数据放在那里等着用

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。 而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素, 那后面绝大多数元素占用的空间都白白浪费了。所以,如果列表元素可以按照某种算法推算出来, 那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。

制作生成器的两种方式

(一)

将列表推导式 [ ] 改成==()==

t = [i for i in range(100)]
print(type(t))  # <class 'list'>
t1 = (i for i in range(100))
print(type(t1))  # <class 'generator'>
(二)

def定义的函数中用yield。

def test1():
    print(1)
    print(2)
    print(3)
    return 123


def test2():
    print("----4----")
    yield 4
    print("----5----")
    num = yield
    print("----6----num=", num)
    yield
    return 466


t1 = test1()  # 会执行test1函数中的代码
t2 = test2()  # 不会执行test2中的代码,而是将test2()认为是创建了一个对象

print(type(t1))  # <class 'int'>
print(type(t2))  # <class 'generator'> 这就是生成器

只要在def中有yield关键字的 就称为 生成器,可以用next()来获取生成器的数据,生成器是可以迭代的。

def gen():
    i = 0
    yield i
    i += 1
    num = yield 200
    print(num)
    i += 1
    yield 100


g = gen()

print(next(g))  # 0
print(next(g))  # 200

我们除了可以使用next()函数来唤醒生成器继续执行之外,还可以使用send()函数来唤醒执行。

send唤醒作用:可以在唤醒前的同时向段点传入一个附加数据

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


g = gen()
print(next(g))  # 0,打印完不动了卡在yield中
# 打印完0之后卡在第一次yield中这是send传参给temp,所以打印完20 i+1,
# 又进入循环卡到yield,yield返回i值所以打印1,此时程序又卡在第二次的yield上。
print(g.send(20))  # 20,1
# 打印完1之后卡在第二次yield中这是send传参给temp,所以打印完12 i+1,
# 又进入循环卡到yield,yield返回i值所以打印2,此时程序又卡在第三次的yield上。
print(g.send(12))  # 12,2
#这块有点难理解,需要慢慢一步一步细心走!!!

总结

  • 使用了yield关键字的函数就不再是函数,而是生成器。
  • yield关键字有两点作用:
    • 保存当前运行状态(断点),然后暂停执行,即将生成器(函数)挂起。
    • 将yield关键字后面表达式的值作为返回值返回,此时可以理解为起到了return的作用
  • 可以使用next()函数让生成器从断点处继续执行,即唤醒生成器(函数)
  • Python3中的生成器可以使用return返回最终运行的返回值
  • 生成器是这样一个函数,它记住上一次返回时在函数体中的位置。对生成器函数的第二次(或第 n 次)调用跳转至该函数中间,而上次调用的所有局部变量都保持不变。
  • 生成器不仅“记住”了它数据状态;生成器还“记住”了它在流控制构造(在命令式编程中,这种构造不只是数据值)中的位置。

生成器的特点:存储的是生成数据的方式(即算法),而不是存储生成的数据,因此节约内存

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值