目录:
1.生成器介绍
2.生成器举例
3.生成器应用
1.生成器介绍
生成器指的是生成器对象,可以由生成器表达式得到,也可以使用yield关键字得到一个生成器函数,调用这个函数得到一个生成器对象
生成器函数:
函数体中包含yield语句的函数,返回生成器对象
生成器对象,是一个可迭代对象,是一个迭代器
生成器对象,是延迟计算,惰性求值的
2.生成器举例
普通的函数调用fn(),函数会立即执行完毕,但是生成器函数可以使用next函数多次执行
>>> y = (i for i in range(5))
>>> print(type(y))
<class 'generator'>
>>> print(next(y))
0
...
>>> print(next(y))
4
>>> print(next(y))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
生成器函数等价于生成器表达式,只不过生成器函数可以更加的复杂
>>> def inc():
... for i in range(5):
... yield i
>>> print(type(inc))
<class 'function'>
>>> print(type(inc()))
<class 'generator'>
>>> x = inc()
>>> print(type(x))
<class 'generator'>
>>> print(next(x))
0
>>> for y in x:
... print(y,'*')
1 *
2 *
3 *
4 *
>>> for y in x:
... print(y,'---')
>>>
在生成器函数中,使用多个yield语句,执行一次会暂停执行,把yield表达式的只返回
再次执行会执行到下一个yield语句
如果函数没有显示return语句,如果生成器函数执行到结尾,一样会抛出StopIteration异常
return语句依然可以终止函数运行,但return语句的返回值不能被获取到 return会导致无法继续获取下一个值,抛出StopIteration异常
>>> def gen():
... print('line 1')
... yield 1
... print('line 2')
... yield 2
... print('line 3')
... return 3
>>> next(gen())
line 1
1
>>> next(gen())
line 1
1
>>> g = gen()
>>> print(next(g))
line 1
1
>>> print(next(g))
line 2
2
>>> print(next(g))
line 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration: 3
>>> print(next(g,'End'))
End
3.生成器应用
3.1无限循环
正确写法
>>> def counter():
... i=0
... while True:
... i += 1
... yield i
>>> def inc(c):
... return next(c)
>>> c = counter()
>>> print(inc(c))
1
>>> print(inc(c))
2
错误写法
>>> def counter():
... i = 0
... while True:
... i += 1
... yield i
>>> def inc():
... c = counter()
... return next(c)
>>> print(inc())
1
>>> print(inc())
1
3.2计数器
不使用匿名函数
>>> def inc():
... def counter():
... i = 0
... while True:
... i += 1
... yield i
... c = counter()
... def _inc():
... return next(c)
... return _inc
>>> foo = inc()
>>> print(foo())
1
>>> print(foo())
2
使用匿名函数
>>> def inc():
... def counter():
... i = 0
... while True:
... i += 1
... yield i
... c = counter()
... return lambda:next(c)
>>> foo = inc()
>>> print(foo())
1
>>> print(foo())
2
3.3处理递归问题
原始代码
>>> def fib():
... x = 0
... y = 1
... while True:
... yield y
... x,y=y,x+y
>>> foo=fib()
>>> for _ in range(5):
... print(next(foo))
1
1
2
3
5
>>> for _ in range(3):
... next(foo)
... print(next(foo))
8
13
21
34
55
89
等效代码
>>> pre = 0
>>> cur = 1
>>> print(pre,cur,end=' ')
0 1
>>> def fib1(n,pre=0,cur=1):
... pre,cur=cur,pre+cur
... print(cur,end = ' ')
... if n == 2:
... return
... fib1(n-1,pre,cur)
>>> fib1(13)
1 2 3 5 8 13 21 34 55 89 144 233
网友评论