生成器

一. 生成器
生成器的本质就是迭代器,在python中有三种方式可以获取生成器
1.通过生成器函数
2.通过各种推导式
3.通过数据转换也可以获取生成器
先看一个简单的函数
def func():
print("111") #在函数执行过程中会被打印出来
   return 222
ret = func()
print(ret) #222

将函数中的return 换成yield 就成了生成器函数
def func():
print("111")
yield 222
ret = func()
print(ret) #<generator object func at 0x01722660>
得到的结果是一个生成器, 所以可以通过__next__()来执行

def func():
print("111")
yield 222
g = func() #这时候函数不执行,而是获取到生成器
ret = g.__next__() #这时候函数才会执行,yield的作用和return一样,也是返回数据
print(ret) #222


*** return 和 yield 的区别:
return是直接停止函数
yield 是分段执行函数

def func():
print("111")
yield 222
   print("333")
yield 444
g = func()
ret = g.__next__()
print(ret) #222
ret2 = g.__next__()
print(ret2) #333
ret3 = g.__next__() #最后一个yield执行完毕后,再次__next__()程序会报错
print(ret3)
当程序运行完最后一个yield,那么后面继续进行__next__()程序会报错

二.生成器的作用
生成器有什么作用呢? 比如说生产10000件衣服,但是一次性生产这么多,没有这么多学生,很麻烦.
最好是来一个学生,就让Jack Jones生产一件.

def colth():
lst = []
for i in range(0,1000):
lst.append("衣服"+str(i))
return lst #直接就return 10000件衣服
cl = cloth()

如何可以一件一件生产呢?
def cloth():
for i in range(0,10000):
yield "衣服"+str(i)
cl = cloth() #产生一个生成器
print(cl.__next__())
print(cl.__next__())
print(cl.__next__())

区别:第一种是直接一次性全部拿出来,会很占内存.
第二种使用生成器,一次就生产一个. 用多少生产多少.

生成器是一个一个的指向下一个.
__next__()到哪,指针就指到哪,下一次继续获取指针指向的值

三. 生成器中 send()和__next__的区别:
  • send 和__next__()一样都可以让生成器执行到下一个yield 的位置
  • send可以给上一个yield 的位置传递值, 不能给最后一个yield 发送值
  • 在第一次使用代码的时候不能使用send()

def eat():
print("吃什么啊?")
a = yield "馒头"
print("a=",a)
b = yield "大饼" #等号左边是yield的返回值, 等号右边是send传递进去的值
print("b=",b)
c = yield "韭菜盒子"
print("c=",c)
yield "GAME OVER"
gen = eat() #获取生成器
ret1 = gen.__next__()#获取第一个值馒头
print(ret1) #馒头
ret2 = gen.send("胡辣汤")#把"胡辣汤"传递给第一个yield的a,并且执行到下一个yield "大饼", 把返回值给ret2
print(ret2) #大饼
ret3 = gen.send("狗粮") #把"狗粮"赋值给b,同时返回一个"韭菜盒子"
print(ret3)#韭菜盒子
ret4 = gen.send("猫粮") #把"猫粮"赋值给c,同时返回一个 GAME OVER
print(ret4) #game over

*** 四. 生成器可以使用for 循环获取内部的元素:
def func():
print(111)
yield 222
print(333)
yield 444
print(555)
yield 666

g = func()#获取生成器
for i in g: # g是生成器也就是迭代器,对于迭代器来说是可以进行for循环的,所以可以对g 进行for循环
print(i)
"""
111
222
333
444
555
666
"""
#将可迭代对象转化成迭代器
#内部使用__next__方法,一个一个取值
 
原文地址:https://www.cnblogs.com/kenD/p/9468696.html