iterator and generator
参考:https://anandology.com/python-practice-book/iterators.html
1 iterator
-
一个定义了
__iter__()
和__next__()
方法的类实例化的对象就是一个iterator。iterator可以被for
循环依次提取内容,同时可以使用next()
函数或者__next__()
方法依次获取迭代器对象中的下一个内容,直到抛出StopIteration
异常而终止这一过程 -
只具备
__iter__()
方法,而不具备__next__()
方法实例化的对象称为可迭代对象(iterable object),但不是迭代器(iterator)。可迭代对象可以被for
循环调用,但没有__next__()
方法,不能被next()
函数调用; -
可迭代对象可以转化为迭代器,转化方式为
iter(iteratable object)
-
iterator类的定义方式比较固定,通常只要在类中如下增加
__iter__()
和__next__()
方法即可:class ClassName(object): ... def __iter__(self): return self def __next__(self): if ...: # 定义用于下一次获取的元素 pass else: # 如果iterator没有elements了,抛异常 raise StopIteration
2 generator
(1) 创建生成器对象
-
生成器就是一种迭代器,有两种创建生成器对象的方式:
- 生成器函数: 类似普通函数,但用
yield
返回值; - 生成器表达式: 类似列表快速创建,但采用圆括号“()”;
- 生成器函数: 类似普通函数,但用
-
采用生成器函数创建生成器对象,例如:
def yrange(n): i = 0 while i < n: yield i i += 1
-
yield
关键字,对上述yrange()
函数生成的对象执行__next__()
方法或next()
函数时,循环在执行到yield
行时停止并返回值i。再次执行next时,将加1,遇到yield
行再次停止,并放回当前值i。如此循环往复,直到抛出StopIteration
异常。 -
使用生成器表达式快速创建生成器对象,例如:
# 创建生成器对象x_1和x_2 x_1 = (x for x in range(10)) #类似列表生成,但非[],而是() x_2 = (x*x for x in range(10))
(2) 生成器优点
- 生成器表达式是对内存空间的优化。 他们不需要像方括号的列表解析一样,一次构造出整个结果列表。他们运行起来比列表解析式可能稍慢一些,因此他们对于非常大的结果集合运算是最优的选择。