在python中,我们经常使用for语句循环遍历可迭代的对象(list,string,dict,tuple)等对象,这些对象都被称为可迭代对象
迭代器
迭代器对象要求支持迭代器协议的对象,在Python中,支持迭代器协议就是实现对象的iter()()和next()方法。其中iter()()方法返回迭代器对象本身;next()方法返回容器的下一个元素,在结尾时引发StopIteration异常。
iter()和next()方法
这两个方法是迭代器最基本的方法,一个用来获得迭代器对象,一个用来获取容器中的下一个元素。
对于可迭代对象,可以使用内建函数iter()来获取它的迭代器对象
list = ['a', 'v', 'a']
# 迭代器的生成,将可以迭代的对象变成迭代器
iter_list = iter(list)
# 调用迭代器里面的函数
first = next(iter_list)
备注:当我们使用for语句循环的时候是只能遍历得到本次的元素的,迭代器可以获取得到下一个元素
生成器
在Python中,使用生成器可以很方便的支持迭代器协议。生成器通过生成器函数产生,生成器函数可以通过常规的def语句来定义,但是不用return返回,而是用yield一次返回一个结果,在每个结果之间挂起和继续它们的状态,来自动实现迭代协议。
yield内部是一个状态机,维护着挂起和继续的状态
# 生成器的例子使用
def Zrange(n):
i = 0
while i < n:
yield i
i += 1
Zrange = Zrange(3)
print(Zrange)
在这个例子中,定义了一个生成器函数,函数返回一个生成器对象,然后就可以通过for语句进行迭代访问了。
其实,生成器函数返回生成器的迭代器。 “生成器的迭代器”这个术语通常被称作”生成器”。要注意的是生成器就是一类特殊的迭代器。作为一个迭代器,生成器必须要定义一些方法,其中一个就是next()。如同迭代器一样,我们可以使用next()函数来获取下一个值。
生成器的执行流程
下面就仔细看看生成器是怎么工作的。
从上面的例子也可以看到,生成器函数跟普通的函数是有很大差别的。
结合上面的例子我们加入一些打印信息,进一步看看生成器的执行流程:
def Zrange(n):
print('开始工作')
i = 0
while i < n:
print('yield之前')
yield i
i += 1
print('yield之后')
print('结束工作')
zrange = Zrange(3)
print('-----------------')
print(next(zrange))
print('-----------------')
print(next(zrange))
print('-----------------')
print(next(zrange))
print('-----------------')
print(next(zrange))
print('-----------------')
总结
- 同iter()方法可以自定义迭代器,for语句遍历也可以通过iter()方法获取迭代器,通过next()方法获取迭代器的下一个元素
- 生成器是一种特殊的迭代器,内部支持了生成器协议,不需要明确定义iter()和next()方法。
- 生成器通过生成器函数产生,生成器函数可以通过常规的def语句来定义,但是不用return返回,而是用yield一次返回一个结果。