11.Python(生成器)

A.创建一个生成器

1.列表生成式的[]变成()

g = (x * x for x in range(10))
print(g.__next__())
print(g.__next__())
print(g.__next__())

 generator保存的是算法,每次调用next(),就会计算出g的下一个值,直到最后一个值计算出来

g = (x * x for x in range(10))
for x in g:
    print(x)

生成器是可迭代对象

2.函数实现

函数中的return改成yield即可

def odd():
    print('step 1')
    yield 1
    print('step 2')
    yield(3)
    print('step 3')
    yield(5)

o=odd()
next(o)
o.__next__()
next(o)

def odd():
    print('step 1')
    yield 1
    print('step 2')
    yield(3)
    print('step 3')
    yield(5)

o=odd()
t=next(o)
print(t)
t=o.__next__()
print(t)
t=next(o)
print(t)

B.generator的send()函数和yield关键字

yield关键字 的作用是 函数与调用者的通信,它不光能够将值返回给调用者,它还可以接收调用者传过来的值,那么怎么实现呢? 调用者通过send()函数将值传递给generator,generator通过 yield 前面的变量来接收,如下:

 但其实 yield关键字 的作用是 函数与调用者的通信,它不光能够将值返回给调用者,它还可以接收调用者传过来的值,那么怎么实现呢? 调用者通过send()函数将值传递给generator,generator通过 yield 前面的变量来接收,如下:

 send函数和next函数的区别就是 send函数可以在执行generator的过程中,给generator发送消息。而next仅仅是接收yield右边的变量值。

生产者消费者模型

import time
def consumer(name):#消费者吃包子
    print('我是[%s],我准备开始吃包子了' %name)
    while True:
        baozi=yield
        time.sleep(1)
        print('%s 很开心的把【%s】吃掉了' %(name,baozi))

def producer():#生产包子
    c = consumer('wupeiqi')
    c.__next__()#执行到了循环的第一个yield,把第一句话打印出来了
    for i in range(5):
        time.sleep(1)
        c.send('包子 %s' %i)

producer()

send函数与yield关键字配合使用可以实现调用者与generator的通信了,那么我们就可以通过他们来实现单一线程切换执行不同函数了。这种操作就叫做协程。

 C.生成器只能遍历一次

def test():
    for i in range(3):
        yield i

t = test()
for i in t:
    print(i)

t1=(i for i in t)#这个循环会执行,但是t已经遍历完了,现在什么都没有
print(list(t1))#所以会输出一个空列表

def test():
    for i in range(3):
        yield i

t = test()

t1=(i for i in t)
t2=(i for i in t1)
print(list(t1))#list是在遍历t1
print(list(t2))#t1被list遍历过以后,已经不能被遍历了

def test():
for i in range(3):
yield i

t = test()

t1=(i for i in t)
t2=(i for i in t1)
print(list(t1))#list是在遍历t1
print(list(t2))#t1list遍历过以后,已经不能被遍历了
原文地址:https://www.cnblogs.com/zhaojiayu/p/13789596.html