14.生成器
生成器:生成器的本质就是迭代器。
生成器的表现形式:
1.生成器函数
2.生成器表达式
生成器函数
生成器函数本质上就是我们自己写的函数,特点是调用函数不执行,返回一个生成器,调用Next方法时会取到一个值,直到取完左后一个,再执行就会报错。
def generator(): print(1) yield 'a' ret=gengrator() #ret拿到的不是一个返回值,而是一个生成器,因为是生成器,这里不执行函数generator print(ret) print(ret.__next__()) #返回生成器的下一个值
执行结果:
<generator object generator at 0x000002C04BADABA0>
1
a
注意:
只要含有yield关键字的函数都是生成器函数,生成器函数在执行后会返回一个生成器
yield必须使用在函数内,且yield不能与return同时使用
从生成器中取值的方法:for和__next__,send()
def generator(): print(1) yield 'a' print(2) yield 'b' print(3) yield 'c' ret=generator() print('<<<',ret.__next__()) #使用next取,方法执行到yield 'a' for i in ret: print(i)
执行结果:
1
<<< a
2
b
3
c
send的使用方法:
def generator():
d=yield 'erer'
print(d)
print('sdfghj')
yield 'c'
ret=generator()
print(ret.__next__())
print(ret.send('hello')) #将'hello'传递给d,然后将程序执行到下一个yield
执行结果:
erer
hello
sdfghj
c
send知识点重点:
send 获取下一个值的效果和 next的基本一致
只是在获取下一个值的时候给上一个 yiled 的位置传递一个数据而已
使用send的注意事项(不能是第一个,也不能是最后一个):
1.在第一次使用生成器时,使用next获取下一个值(要不然send找不到上一个yiled值)
2.最后一个yiled不能接收外部的值
生成器的强制转换:
讲将迭代器中的数据强制转换成list中的数据放入内存中,使用方法list(g)。转换后数据会占用较多内存。
def generator(): yield 'a' yield 'b' yield 'c' ret=generator() c=list(ret) print(c)
执行结果:
['a', 'b', 'c']
生成器函数进阶:
动态求平均值:预激活生成器
def init(f): def inner(*args,**kwargs): g=f(*args,**kwargs) g.__next__() #激活生成器 return g return inner() @init def average(): sum=0 count=0 avg=0 while(1): # a = yield None a = yield avg sum=sum+a count+=1 avg=sum/count g=average() avge=g.send(10) print(avge)
新增关键字:yield from
def gengrator(): a='abcdfe' b='12344'
在函数中想要将a,b中的元素依次的返回,即先返回'a',再‘b’,再‘c’,只使用yield也可以完成,但是代码比较复杂,繁琐。代码如下:
def gengrator():
a='abcdfe'
b='12344'
for i in a:
yield i
for i in b:
yield i
g=gengrator()
print(g.__next__())
print(g.__next__())
执行结果:
a
b
这里就可以使用关键字yield from ,代码如下:(两段代码的作用是完全一致的)
def gengrator(): a='abcdfe' b='12344' yield from a yield from b
g=gengrator()
print(g.__next__())
print(g.__next__())
执行结果:
a
b

浙公网安备 33010602011771号