python-生成器、迭代器理解

迭代器

顾名思义,迭代器就是用于迭代操作(for 循环)的对象,它像列表一样可以迭代获取其中的每一个元素,任何实现了__next__ 方法 (python2 是 next)的对象都可以称为迭代器。

它与列表的区别在于,构建迭代器的时候,不像列表把所有元素一次性加载到内存,而是以一种延迟计算(lazy evaluation)方式返回元素,这正是它的优点。比如列表含有中一千万个整数,需要占超过400M的内存,而迭代器只需要几十个字节的空间。因为它并没有把所有元素装载到内存中,而是等到调用 next 方法时候才返回该元素(按需调用 call by need 的方式,本质上 for 循环就是不断地调用迭代器的next方法)。

以斐波那契数列为例来实现一个迭代器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Fib(object):
def __init__(self, n):
self.pre_pre = 0
self.pre = 1
"""
:param n: int, 指明生成数列的前n个数
"""
self.n = n
# index用来保存当前⽣成到数列中的第几个数了
self.index = 0

def __next__(self):
if self.n > 0 and self.index < self.n:
value = self.pre
self.pre_pre,self.pre = self.pre, self.pre_pre+self.pre
self.index +=1
return value
else:
return StopIteration()

def __iter__(self):
return self

def main():
# 传入 10, 输出10位斐波那契数列 1,1,2,3,5,8,13,21,34,55
resp=[]
n=10
f = Fib(n)
for i in range(0,n):
resp.append(f.__next__())
print(resp)
if __name__ == '__main__':
main()
#[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

生成器

生成器算得上是Python语言中最吸引人的特性之一,生成器其实是一种特殊的迭代器,不过这种迭代器更加优雅。它不需要再像上面的类一样写iter()和next()方法了,只需要一个yiled关键字。 生成器一定是迭代器(反之不成立),因此任何生成器也是以一种懒加载的模式来生成值。用生成器来实现斐波那契数列:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from itertools import islice


def fib():
prev, curr = 0, 1
while True:
yield curr # 循环探针yield
prev, curr = curr, curr + prev


def main():
f = fib()
resp = list(islice(f, 0, 10)) # [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
return resp


if __name__ == '__main__':
print(main())