受内存限制,列表容量有限,且创建较多元素的列表时,只访问前几个元素,后面元素占用的空间就浪费了
生成器:一边循环一边计算,不必创建完整的list,从而节省空间
创建生成器的两种方法:
1、把一个列表生成式[]换成()
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>
2、定义一个函数中包含有yield字段,那该函数就不是一个普通的函数,而是一个生成器generator
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'
注:a,b=b,a+b =右边的先同时计算,再分别赋值给左边、
生成器的调用:一般使用for循环迭代,说明生成器也是一个可迭代的对象。
for循环一般需要给一个判断结束循环
>>> for n in fib(6):
... print(n)
...
1
1
2
3
5
8
使用for循环调用generator时,无法拿到最后的return返回值,需要捕捉
StopIteration
错误,返回值包含在
StopIteration
的
value
中:
>>> 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