一、什么是生成器 | |
二、创建生成器的方法 | 2.1把一个列表生成式的[ ]改成( ),就创建了一个generator 2.2用函数来实现generator 2.3获取fib(6)中的值 2.3.1直接用for循环迭代获取fib(6)中的值: 2.3.2使用next函数抛出StopIteration异常从而获取generator的 return语句的返回值: |
三、获得generator的值 | 3.1使用next()函数获得generator的下一个返回值 3.2使用for循环获取generator的值 |
四、练习 | 打印杨辉三角 |
一、什么是生成器
在python中,这种一边循环一边计算的机制,称为生成器:generator
二、创建生成器的方法
2.1把一个列表生成式的[ ]改成( ),就创建了一个generator
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>
注释:L与g的创建区别仅仅是最外层的[ ]和()的区别,L指的是list,g指的是generator
2.2用函数来实现generator
generator非常强大。如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以使用函数来实现generator
举例:
fibonacci,除第一个数和第二个数除外,其余数都是前两项的和
1,1,2,3,5,8,13,21,34,···
fibonacci用列表生成式写不出来,但是用函数却很容易打印出来
程序:
def fib(max):
n,a,b=0,0,1
while n<max:
print(b)
a,b=b,a+b
n=n+1
return 'done'
执行:
>>> fib(6)
1
1
2
3
5
8
'done'
将fib()函数变成generator:只要将print(b)改为yield b即可:
def fib(max):
n,a,b=0,0,1
while n<max:
print b
a,b=b,a+b
n=n+1
return 'done'
以上generator执行:
>>> f = fib(6)
>>> f
<generator object fib at 0x104feaaa0>
2.3获取fib(6)中的值
2.3.1直接用for循环迭代获取fib(6)中的值:
>> for n in fib(6):
... print(n)
...
1
1
2
3
5
8
cmd窗口下完整generator定义及获取值:
推广:如果一个函数定义中包含yield关键字,那么这个函数就不是普通函数,而是一个generator
2.3.2使用next函数抛出StopIteration异常从而获取generator的 return语句的返回值:
要拿到return语句的返回值,必须捕获StopIteration的错误,返回值包含在StopIteration的value中。而要捕获StopIteration
错误,就要用next()函数一个接着一个的获得generator的值,直到计算到最后一个元素,没有更多元素时抛出StopIteration的错误。
>>> g = fib(6)
>>> while True:
... try:
... x = next(g)
... print('g:', x)
... except StopIteration as e:
... print('Generator return value:', e.value)
... break
...
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done
cmd窗口下获取generator的返回值演示:
使用for n in g 并不能获取generator返回值:
三、获得generator的值
创建generator供以下获取generator值使用
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>
3.1使用next()函数获得generator的下一个返回值
直到计算到最后一个元素,没有更多元素时抛出StopIteration的错误
(注:这种方法基本不会用)
>>> next(g)
0
>>> next(g)
1
>>> next(g)
4
>>> next(g)
9
>>> next(g)
16
>>> next(g)
25
>>> next(g)
36
>>> next(g)
49
>>> next(g)
64
>>> next(g)
81
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
3.2使用for循环获取generator的值
因为generator是可迭代对象,所以可以使用for循环来获取其值
>>> g = (x * x for x in range(10))
>>> for n in g:
... print(n)
...
0
1
4
9
16
25
36
49
64
81
四、练习
打印杨辉三角。该程序段保存在杨辉三角.py
def triangles():
L=[1]
n=1
i=1
while n<=10:
yield L
L=[1]+[L[i]+L[i+1] for i in range(n-1)]+[1]
n=n+1
调用函数代码:
from 杨辉三角 import triangle
g=triangle()
for i in g:
print(i)
cmd运行结果: