生成器

生成器(生成器的本质是保存了一套生成值的算法,每调用一次生成一个值):

目标:需要一个非常大的列表,里面有很多元素,还不想占用太大内存空间。

 

生成器组成方式一:

将生成式的列表改为元组即可。

x = [x for i in range(5)]  --------------->  x = (x for in range(5))      

生成器组成方式二:

包含yield”的函数

def creat_num():

    print('-----start------')

    a,b = 0,1

    for i in range(5):

        yield b  =============>带有关键字“yield”的函数就不再称为函数了,统计称为生成器。“yield”在此将程序拦腰斩断,程序每执行完包含“yield”关键字的这行代码就暂停(并且返回“yield”后面的值,

                                                                                           相当于return b),直到再次被next()调用时再继续往下走。

                               思考:把yield放在最后一行,前面的代码负责生成要返回的值,yield负责暂停循环和return生成的值。

        a,b = b,a+b

    print('-----stop-------')

a = creat_num() ===========>调用这个“函数”时实际返回的是一个对象

next(a)  ========>在生成器对象里包含一个self.__next__()方法,等价于next(self)

for i in a:  =============>注意:尽管生成器是一个对象,依然可以用for来遍历。

    print(i)

def test():

    a = 0

    while a < 5:

        temp = yield a  ==========>注意:因为基本语法规定碰到“=”先执行右边再执行左边,所以此处执行右边后即暂停,所以temp就得不到值了,下次开始时相当于从“temp=”开始执行,即temp得到的值为空。

                                         要想让temp得到值可以使用t.__send__('haha')方法将一个值传进去(即:haha,同时__send__也具有__next__的本领(即让生成器继续往下走一步)。

        print(temp)

        i+=1

t = test()

t.__next__()

t.__next__() ========> 输出结果为None

生成器组成协程:

def test1():

    while 1:

        print('--1--')

        yield None

def test2():

    while 1:

        print('--2--')

        yield None

t1 = test1()

t2 = test2()

while 1:  =======>程序有了“暂停”功能就可以循环切换任务来执行了(即:协程)

    t1.__next__()

    t2.__next__()

原文地址:https://www.cnblogs.com/baihualin/p/10345281.html