python学习第四周之生成器

1.今天学习了python的生成器,首先先通过一个例子来了解一下。

在命令行中输入: [i*2 for i in range(10)],输出结果为:[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

这时我们发现[i*2 for i in range(10)]与以下代码输出结果是一样的,

>>> a=[]
>>> for i in range(10):
...  a.append(i*2)
...
>>> a
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

那么我们将[i*2 for i in range(10)]称之为列表生成式:是代码简洁,直接创建列表,可以一边循环一边计算的机制称为生成器:generator

2.列表list跟生成器generator区别在于最外层的[ ]跟( ),

生成器的特点:

  只有调用才能生成相应的数据;只会记录当前的位置,使用b.__next__()一个一个往后走

如下:当在命令行中输入 (i*2 for i in range(10))

输出结果为生成器的内存地址:<generator object <genexpr> at 0x00C68B30>

只有调用才会输出结果
>>> b=(i*2 for i in range(10))
>>> for i in b:
...    print(i)

3.斐波那契数列:除第一个跟第二个数外,任意一个数可由前两个数相加,如1,1,2,3,5,8,13,21...

1)可以通过如下函数来实现:

def fib(max):
    n,a,b=0,0,1
    while n<max:
        print(b)
        a,b=b,a+b  #相当于 a=0;b=1;t=(b,a+b)
        n=n+1
    return 'done'
fib(10)    #生成10个斐波那契数列,从1开始

 结果为一次性输出10个数据,我们如果将print(b)换为yield b则变为生成器

2)如下则为生成器,可以通过f.__next__()来一个一个输出结果

def fib(max):
    n,a,b=0,0,1
    while n<max:
        yield b #将print(b)变为yield b ,即为生成器
        a, b = b, a + b  # 相当于 a=0;b=1;t=(b,a+b)
        n=n+1
    return 'done'
print(fib(10) )  #输出生成器的内存地址
f=fib(10)

print(f.__next__())
print("---------")
print(f.__next__())
print(f.__next__())  #当next大于10时,使用return 'done',会抛出异常,StopIteration: done

 这种好处是我们可以随时进入函数,随时退出函数,并且可以在函数外进行操作,如果我们想将剩余的数一次性调用,那么我们可以使用for循环

将for循环写在最后一个print(f.__next__())的下面,即可输出其余的数据

print("--start loop--")
for i in f:
    print(i)

注意如果我们使用print(f.__next__()) 大于10次时,程序运行会抛出异常,StopIteration: done,这是因为我们在函数中使用了 return 'done';

如果我们想要抓住这个抛出的异常,那么我们可以使用while循环,将其插入到f=fib(10)后面,如下:

#抓住抛出的异常
g=fib(6)
while True:
    try:
        x=next(g)
        print('g:',x)
    except StopIteration as e:
        print('Generator return value:',e.value)
        break

好的,完结。

今天是入驻博客园第一天,纪念一下!

我会持续更新的

原文地址:https://www.cnblogs.com/wuxiaoru/p/11378628.html