05-生成器:基本使用
目标¶
- 能够用两种方法创建生成器
1. 生成器¶
利用迭代器,我们可以在每次迭代获取数据(通过next()方法)时按照特定的规律进行生成。但是我们在实现一个迭代器时,关于当前迭代到的状态需要我们自己记录,进而才能根据当前状态生成下一个数据。为了达到记录当前状态,并配合next()函数进行迭代使用,我们可以采用更简便的语法,即生成器(generator) 。生成器是一类特殊的迭代器。
2. 创建生成器方法1¶
要创建一个生成器,有很多种方法。第一种方法很简单,只要把一个列表生成式的 [ ] 改成 ( )
In [15]: L = [ x*2 for x in range(5)]
In [16]: L
Out[16]: [0, 2, 4, 6, 8]
In [17]: G = ( x*2 for x in range(5))
In [18]: G
Out[18]: <generator object <genexpr> at 0x7f626c132db0>
In [19]:
创建 L 和 G 的区别仅在于最外层的 [ ] 和 ( ) , L 是一个列表,而 G 是一个生成器。我们可以直接打印出列表L的每一个元素,而对于生成器G,我们可以按照迭代器的使用方法来使用,即可以通过next()函数、for循环、list()等方法使用。
In [19]: next(G)
Out[19]: 0
In [20]: next(G)
Out[20]: 2
In [21]: next(G)
Out[21]: 4
In [22]: next(G)
Out[22]: 6
In [23]: next(G)
Out[23]: 8
In [24]: next(G)
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-24-380e167d6934> in <module>()
----> 1 next(G)
StopIteration:
In [25]:
In [26]: G = ( x*2 for x in range(5))
In [27]: for x in G:
....: print(x)
....:
0
2
4
6
8
In [28]:
3. 创建生成器方法2¶
generator非常强大。如果推算的算法比较复杂,用类似列表生成式的 for 循环无法实现的时候,还可以用函数来实现。
我们仍然用上一节提到的斐波那契数列来举例,回想我们在上一节用迭代器的实现方式:
def fibonacci(n):
# 定义斐波那契数列的前2个值
a = 0
b = 1
# 定义当前的位置
current_index = 0
print("------------1111-----------")
while current_index < n:
# 定义要返回的值
result = a
# 生成新的 a、b值
a, b = b, a+b
# 让当前值+1
current_index += 1
print("-----------2222----------")
yield result
print("-----------3333------------")
# 生成器,生成斐波那契数列
fib = fibonacci(5)
value = next(fib)
print(value)
value = next(fib)
print(value)
------------1111-----------
-----------2222----------
0
-----------3333------------
-----------2222----------
1
Process finished with exit code 0
-
使用了yield关键字的函数不再是函数,而是生成器。(使用了yield的函数就是生成器)
-
yield关键字有两点作用:
保存当前运行状态(断点),然后暂停执行,即将生成器(函数)挂起
将yield关键字后面表达式的值作为返回值返回,此时可以理解为起到了return的作用