0
点赞
收藏
分享

微信扫一扫

Python快速而美丽[v1.0.0][生成器]


简单生成器

>>> 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 0x000000D25E141B88>
>>> G.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'generator' object has no attribute 'next'
>>> G.__next__()
0
>>> G.__next__()
1
>>> G.__next__()
4
>>> G.__next__()
9
>>> G.__next__()
16
>>> G.__next__()
25
>>> G.__next__()
36
>>> G.__next__()
49
>>> G.__next__()
64
>>> G.__next__()
81
>>> G.__next__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

解析

创建Generator,有很多种方法,第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个Generator

Generator保存的是算法,每次调用next(),就计算出下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误

在代码中我们调用next()函数报错,因为在Python3之后next()函数改为了__next__()

这样使用__next__()函数来让生成器生成数据的方式太麻烦了,虽然生成器不是列表,但我们仍然可以使用for循环

>>> G = (x * x for x in range(10))
>>> for e in G:
... print(e)
...
0
1
4
9
16
25
36
49
64
81

生成器进阶

有序的数列我们可以使用列表生成器来生成每一个元素,然后用for循环来迭代它,如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现

>>> def fibonacci(end):
... a, b, c = 0, 0, 1
... while a < end:
... print(c)
... b, c = c, b+c
... a = a+1
...
>>> fibonacci(10)
1
1
2
3
5
8
13
21
34
55
>>>

解析

定义generator的另一种方法。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator。

fibonacci函数定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,然而它还不是个生成器,距离生成器仅一步之遥,只需要将只需要把print©改为yield©即可

generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行

>>> def fibonacci(end):
... a, b, c = 0,0,1
... while a < end:
... yield(c)
... b,c = c, b+c
... a=a+1
...
>>> fibonacci(10)
<generator object fibonacci at 0x000000D25E2792A0>
>>> num = fibonacci(10)
>>> num.__next__()
1
>>> num.__next__()
1
>>> num.__next__()
2
>>> num.__next__()
3
>>> num.__next__()
5
>>> for i in fibonacci(10):
... print(i)
...
1
1
2
3
5
8
13
21
34
55



举报

相关推荐

0 条评论