Python知识点进阶——生成器

生成器

      为什么要将列表转化为迭代器?

      因为列表太大的话用内存太大,做成迭代器可以节省空间,用的时候再拿出部分。

      生成器是不会把结果保存在一个系列中,而是保存生成器的状态,在每次进行迭代时返回一个值,知道遇到StopIteration异常结束。


创建生成器

      先看个例子


当要生成的list非常大时,会抛出异常,存储报错。

那怎样生成这种巨大的list呢?


可以看出b是一个generator,也就是生成器模式

生成器的创建很简单,将列表生成式的中括号改成小括号即可

注意:这里说的不是列表,因为列表的中括号改成小括号是元组!


如果想要生成一个内容,可用next()函数:


直到最后会抛出异常,也就是到达了生成器的末端


函数进化为生成器


将函数中的return换成yield,函数就变成了生成器。


当我们调用时,发现返回的是生成器对象。为了拿到数据,我们可以使用next()函数

不过在此之前,我们先要用一个变量去接收这个生成器对象,并且为了观察生成器的特点,我们对函数进行修改


当我们使用next(a)对生成器操作一次时,会返回循环一次的值

也就是在yield处结束本次运行

但是它的特点就是下次使用next(a)时,接着上次的断点继续运行,直到下一个yield

不断使用next(a),直到运行到生成器结尾处,会出现StopIteration异常。


使用for循环调用生成器


与next()等价的方式



send()


每次运行,除了返回下一个,还会打印出None

注意item=yield i 这句,首先执行的等号右边,yield返回,此时,返回生成器一个对象,并且中断

下次使用f.__next__()时候,并没有传内容进去,可认为yield i这整个赋值给item的为None,所以item打印出为None

为了做比较,引入send()


send()可看做next()的增强版,除了可以使用next()功能,还能传入一个值到上次yield断开地方的整体表达式(这里是yield i)


多任务——协程


当我们在while主程序中,先使用f1.__next__()调用生成器func1,因为func1的循环条件始终为真,所以先打印(执行装入操作)然后遇到yield退出生成器func1,回到主程序

接着执行f2.__next__()调用生成器func2,像之前调用func1一样,先打印(执行打包操作)然后遇到yield退出生成器func2,回到主程序。因为主程序循环条件始终为真,所以继续像之前一样,接着调用,如此往复。这里使用打断来停止程序执行,不然会不断执行下去,由于两个生成器交替执行,很快,就像在多任务执行。

转载于:https://www.cnblogs.com/Mayny/p/9374170.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值