2018-06-14 Python生成器

2018-06-14  本文已影响0人  Future石

生成器

创建生成器的方法

1.列表生成式将中括号改成小括号
#列表生成式
a = [x*2 for x in range(10)]
#生成器
b = (x*2 for x in range(10))
2.在def中使用yield关键字,不是创建方法,而是创建了一个生成器

斐波拉契数列作为演示
除了第一个,第二个数字以外,任意一个数都由前面两个数相加得到:1,1,2,3,5,8,13,21,34......
创建一个生成斐波拉契数列的方法

def fib(times):
    n = 0
    a,b = 0,1
    while n < times:
        print b
        a,b = b,a+b
        n += 1
    return 'Done'
fib(5)

创建一个生成斐波拉契数列的生成器

def fib(times):
    n = 0
    a,b = 0,1
    while n < times:
        yield b
        a,b = b,a+b
        n += 1
a = fib(6)
next(a)
next(a)
a.__next__()

yield的运行机制

next(a),a.__next__()调用效果相同

def fib(times):
    n = 0
    a,b = 0,1
    while n < times:
        print ("----1----")
        yield b
        print ("----2----")
        a,b = b,a+b
        n += 1
a = test()

#for循环写起来更简洁
def fib(times):
    a,b=0,1
    for n in range(times):
        yield b
        a,b = b,a+b

#两种调用方式等效
next(a)
a.__next__()

运行至yield b 时停止,等到下一次调用,从a,b=b,a+b 处再次运行到下一次yield b时再次停止,循环♻️

send()方法和next()方法

temp = yield i并不是把yield的值赋值给temp,而是在运行到yield i时接收send()传进的值,如果没传,等同传了None(send(None)或者next())。

重点 传入的值需要变量来接收,每次传入的值到下一次yield运行时需要重新传值,如果没传则又变成None

def test():
    i = 0
    while i < 5:
# 传值用变量temp接收
        temp = yield I
        print (temp)
        i += 1

a = test()

send(None)把None值给temp, next(a)没有传值,相当于传了个None,效果一致

ps:负责生成数列的是yield ,next()和send()只是触发yield。
生成器第一次调用,不能使用send("haha")传值,需要先用next()或者先传个Nonea.send(None)先调用一次生成器才可以。

生成器的作用 - 完成多任务

任务切换的足够快,可以看成多个任务一起执行,这是一种多任务的实现方式-协程
多任务实现的三种方式:线程,进程,协程

def test1():
    while True:
        print ("--1--")
        yield None

def test2():
    while True:
        print("--2--")
        yield None

t1 = test1()
t2 = test2()

while True:
    t1.__next__()
    t2.__next__()
上一篇下一篇

猜你喜欢

热点阅读