在Python中,一边循环一边计算的机制,称为生成器(Generator)。

 

自定义生成器

通过yeild 表达式定义生成器

案例1

yield一次返回一个结果,并且会冻结当前函数的状态

def my_gen():
    yield 1
    yield 2
    yield 3

 

next函数可以迭代生成器的返回值 

生成器其实也是迭代器也是可迭代对象,可以使用next方法获取可迭代对象

ret = my_gen()
print(next(ret))        #ret值为1
print(next(ret))        #ret值为2
print(next(ret))        #ret值为3

 

 

案例2

利用生成器遍历输出一个1~100000的序列

前面说生成器是迭代器也是可迭代对象,那么可以使用next方法也可以用for in 遍历

def my_gen(start,end):
    index = start
    while index <= end:
        yield index
        index+=1


ret = my_gen(1,100000)
for x in ret:
    print(x)

这样就不必创建完整的list,从而节省大量的空间

 

案例3

生成斐波那契数列 1 1 2 3 5 .....

def fib(count):
    index = 1
    a,b = 0,1
    while index <= count:
        yield b
        c = b
        b = a + b
        a = c
        index +=1

num = fib(5)
for x in num:
    print(x)

 

 

案例4

多任务同步进行

利用生成器,将两个任务进行往复的切换(这样就达到了`多进程`的效果),直到任务结束。

def music(count):
    index =0
    while index <= count:
        print('任务一%d次' % index)
        index +=1
        yield None
    raise StopIteration()



def movie(count):
    index =0
    while index <= count:
        print('任务二%d次' % index)
        index +=1
        yield None
    raise StopIteration()

def main():
    music_iter = music(10)
    movie_iter = movie(20)
    music_stop = False
    movie_stop = False
    while True:
        try:
            next(music_iter)
        except StopIteration:
            print('任务一结束')
            music_stop = True

        try:
            next(movie_iter)
        except StopIteration:
            print('任务二结束')
            movie_stop = True

        if music_stop and movie_stop:
            break

if __name__ == '__main__':
    main()