一、二者定义
生成器:generator 英文字面是发动机的意思,目的就是在 循环的过程中不断推算出后面的元素,这样就可以不用一次性创建出所有的元素,从而节省空间。
迭代器:迭代器iterator是一种对象,个人理解相当于游标,如果一个对象是可迭代(iterable)的那么就可以用iterator对其进行迭代。在Python中可以用isinstance()判断一个对象是否是可迭代的。
二、生成器的创建
第一种:
>>> 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>
对比列表,生成器是将[]变为()。因为列表和生成器都是可迭代的,都可以用for来进行遍历操作,但是生成器可以用next()函数依次来获取返回值,若到末端空了,则抛出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
第二种:用函数来实现生成器。当推算的算法无法用列表生成式进行操作时,可以用函数实现。
例如斐波那契数列,第n(n≥3)个数是前两个数的和。如果要生成斐波那契数列则可以用函数打印和生成器生成
def fib(max): def fib(max):
n, a, b = 0, 0, 1 n, a, b = 0, 0, 1
while n < max: while n < max:
print(b) yield(b)
a, b = b, a + b a,b=b,a+b
n = n + 1 n=n+1
return return
对比两种操作,将函数中的print(b)改为yield(b)就变成了生成器。函数是顺序执行,遇到语return句或者最后一行函数语句就返回。而变成generator的函数,在每次调next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。yield由;英文意思屈服,可以理解,执行到那就怂了不执行了,等再次调用next()时,又不怂了。此时函数变成了生成器就可以迭代了,所以可以用for来迭代fib(max)函数。
>>> for n in fib(6):
... print(n)
...
1
1
2
3
5
8