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

 

posted @ 2020-10-12 20:28  maday  阅读(72)  评论(0)    收藏  举报