多任务-python实现-生成器相关(2.1.13)

@

1.概念

 通过列表生成式,我们可以直接创建一个列表,但是,受到内存限制,列表容量肯定是有限的,而且创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

  所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间,在Python中,这种一边循环一边计算的机制,称为生成器:generator

  生成器是一个特殊的程序,可以被用作控制循环的迭代行为,python中生成器是迭代器的一种,使用yield返回值函数,每次调用yield会暂停,而可以使用next()函数和send()函数恢复生成器。

  生成器类似于返回值为数组的一个函数,这个函数可以接受参数,可以被调用,但是,不同于一般的函数会一次性返回包括了所有数值的数组,生成器一次只能产生一个值,这样消耗的内存数量将大大减小,而且允许调用函数可以很快的处理前几个返回值,因此生成器看起来像是一个函数,但是表现得却像是迭代器
  

简单说生成器是一种特殊的迭代器

2.创建方法

第一种方法

l = [x*2 for x in range(5)]
print(l)
#[0, 2, 4, 6, 8]
nums = (x*2 for x in range(5))
print(nums)
#<generator object <genexpr> at 0x000002631D352360>

可以使用list或者tuple来接收生成器
生成器返回的是一个生成数据的方式,更加的节省空间

第二种方法

def fib(n):
    current = 0
    num1 , num2 = 0,1
    while current<n:
        num = num1
        num1 , num2 = num2,num1+num2
        current +=1
        yield  num
    return 'done'


# for i in fib(10):
#     print(i)

f = fib(10)
print(next(f),next(f),next(f),next(f))
#0 1 1 2


while True:
    try:
        ret  = next(f)
        print(ret)
    except Exception as ret:
        print(ret)
        break

如果在调用函数的时候,函数里面有yiled,说明创建了一个生成器对象
使用next运行‘游标’
最下面的死循环,判断next后面是否有值,如果没有就返回的是异常信息return

3.通过send方式来启动

def aa():
    for i  in range(10):
        a = yield 1
        print(a)


f = aa()
next(f)
d = f.send("11")
#11

send一般不放在第一次启动生成器,如果非要这么做,那么传递none
send就是传递参数用的

原文地址:https://www.cnblogs.com/simon-idea/p/11358611.html