08-python学习笔记-生成器:generator

来源:互联网 发布:dnf上号就数据异常 编辑:程序博客网 时间:2024/05/29 03:00

2017.6.8


学习资料:廖雪峰的官方网站


1、生成器

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

如果可以通过一种算法,根据已经给出的数,通过循环来不断推算出后面的元素,那么我们就不必创建一个完整的list,可以节省大量的空间。

在Python中,这种一边循环一边计算的机制,称为生成器:generator。

创建一个generator

方法1

方法1:把一个列表生成式的[]改成(),就创建了一个generator:

L = [x*x for x in range(10)]print(L)g = (x*x for x in range(10))for n in g:    print(n)

方法2

方法2:把函数定义中的print(b)改为yield b

例子:
如果我们要生成斐波拉契数列(Fibonacci)

1, 1, 2, 3, 5, 8, 13, 21, 34, …

这个数列的规律为:除第一个和第二个数外,任意一个数都可由前两个数相加得到:
如果我们用列表生成式的话,是写不出来的。

下面首先用函数写

def fib(max):    n =0    a,b = 0 ,1    while n <max:        print(b)        a,b=b,a+b        # t=(b,a+b)        # a=t[0]        # b=t[1]        n=n+1    return  'done'fib(6)

注意赋值语句

a,b=b,a+b

相当于

# t=(b,a+b)# a=t[0]# b=t[1]

这里没有显示的写出临时变量t进行赋值
上述输出结果为

112358

可以看出,fib函数是定义了一个推算规则,可以从前两个元素推算出后续的n个数列,这个逻辑和generator很像,如果要把这个函数改为generator,只需要把函数中的print(b)改为yield b就可以。

def fib(max):    n =0    a,b = 0 ,1    while n <max:        yield (b)        a,b=b,a+b        # t=(b,a+b)        # a=t[0]        # b=t[1]        n=n+1    return  'done'for y in fib(4):    print(y)

输出结果为

1123

上述的就是第2种方法来定义generator。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:

小结

generator的工作原理:函数是在for循环的过程中不断计算出下一个元素,并在适当的条件结束for循环。但是对于函数改成的generator来说,遇到return语句或者执行到函数体最后一行语句,就是结束generator的指令,for循环随之结束。并且对generator的调用,实际返回是一个generator的对象

>>> g = fib(6)>>> g<generator object fib at 0x1022ef948>

而普通函数调用直接返回结果:

>>> r = abs(-6)>>> r6