概述
补充一个知识点:
生成器的创建方式有两种
(1)生成器推导式
列表推导式的 【】改成()就成了生成器
而不是元组推导式
想要用推导式得到一个元组,需要用 tuple() 将推导式得到的生成器转化成元组
ge=(i for i in range(9))
print(ge)
print(type(ge))
>>> <generator object <genexpr> at 0x000002A00A1E42E0>
>>> <class 'generator'>
此时,print(ge)打印出来的是个生成器对象,而不是具体内容
(2)使用yield关键字
找了一大串文章,看的眼花缭乱,也没看懂 自己写理解吧
1.使用yield的函数就不是函数了 是一个生成器generator
生成器内置有一个__next__(即next()函数),这个是精髓
即 看到yield——系统识别这是一个生成器,不是函数——给这个生成器内置一个next(),给其他对象调用
2.所以调用带yield的所谓函数时,其实就是调用了生成器
3.调用生成器返回的是一个可迭代对象
4.命令调用生成器的时候,只是把这个生成器拿出来准备使用,但并没有直接开始使用,不执行代码
5.只有当调用生成器的__next__方法时,代码才会往下执行
6.但是代码执行到yield语句时,就中断了,返回一个迭代值 即yield xxx
7.再调用一次__next__时,会用中断处,也就是从yield的下一行语句还是继续执行
8.写代码的时候要注意考虑 哪些代码写在yield上面,哪些代码写在yield下面
第一次调用next()时——执行代码到yield这一行 ,中断
第二次调用next()时——从yield下一行还是执行,直到第二次循环到yield,遇到yield又中断
9.当一直调用next()到最后一个yield值后,如果再次调用next(),会抛出错误
意思是系统告诉你,迭代已经全部结束了,没有东西再迭代了,不能一直循环下去
10.重点:
for循环:
for循环机制
1.for循环会自动调用可迭代对象的next()方法,不需要写代码
2.为什么for会循环,其实就是因为自动调用了对象的next()
3.所以也可以这么说,如果某个对象内置方法里没有__next__,
那么此对象不可迭代,不可for遍历
4.for循环会自动捕捉next()最后的异常,从而终止再次调用next()
一句话理解为什么要用yield,为什么要用生成器
最常用的生成器:range
比如range(0,10000000)
我不管你range()里要生成多少个,我每次只生成一个,一个用掉了再生成下一个,用的内存空间是固定的
而如果用列表的形式,那内存就不固定了,有可能就会很大,知道爆掉
而且列表常驻内存,生成器用一个拿一个,资源不会浪费
def func(): list_a=[1,2,3,4,5] for i in list_a: print(i) yield i print(i) g=func() g.__next__() #或者next(g) g.__next__() #或者next(g)
-------------------------------
第一次运行g.__next__() 打印结果1
第二次运行g.__next__() 打印结果1 2
因为第二次运行时,运行的是第一次循环yield下面的print(i)+第二次循环运行到yield,也会打印一次print(i)
最后
以上就是端庄大叔为你收集整理的生成器 generator yield for循环调用的全部内容,希望文章能够帮你解决生成器 generator yield for循环调用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复