Python中生成器和迭代器的区别(代码在Python3.5下测试):
对于list、string、tuple、dict等这些容器对象,使用for循环遍历是很方便的。在后台for语句对容器对象调用iter()
函数。iter()
是python内置函数。
iter()
函数会返回一个定义了next()
方法的迭代器对象,它在容器中逐个访问容器内的元素。next()
也是python内置函数。在没有后续元素时,next()
会抛出一个StopIteration异常,通知for语句循环结束。
迭代器是用来帮助我们记录每次迭代访问到的位置,当我们对迭代器使用next()函数的时候,迭代器会向我们返回它所记录位置的下一个位置的数据。实际上,在使用next()
函数的时候,调用的就是迭代器对象的_next_方法(Python3中是对象的_next_方法,Python2中是对象的next()
方法)。所以,我们要想构造一个迭代器,就要实现它的_next_方法。但这还不够,python要求迭代器本身也是可迭代的,所以我们还要为迭代器实现_iter_方法,而_iter_方法要返回一个迭代器,迭代器自身正是一个迭代器,所以迭代器的_iter_方法返回自身self即可。
1,迭代器协议:对象需要提供next()
方法,它要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代。
2,可迭代对象:实现了迭代器协议对象。list、tuple、dict都是Iterable(可迭代对象),但不是Iterator(迭代器对象)。但可以使用内建函数iter()
,把这些都变成Iterable(可迭代器对象)。
3,for item in Iterable 循环的本质就是先通过iter()
函数获取可迭代对象Iterable的迭代器,然后对获取到的迭代器不断调用next()
方法来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束
# 随便定义一个listlistArray=[1,2,3]# 使用iter()函数iterName=iter(listArray)print(iterName)# 结果如下:是一个列表list的迭代器# <list_iterator object at 0x0000017B0D984278>print(next(iterName))print(next(iterName))print(next(iterName))print(next(iterName))#没有迭代到下一个元素,直接抛出异常# 1# 2# 3# Traceback (most recent call last):# File "Test07.py", line 32, in <module># StopIteration
Python中一个实现了_iter_方法和_next_方法的类对象,就是迭代器,如下案例是计算菲波那切数列的案例
class Fib(object): def __init__(self, max): super(Fib, self).__init__() self.max = max def __iter__(self): self.a = 0 self.b = 1 return self def __next__(self): fib = self.a if fib > self.max: raise StopIteration self.a, self.b = self.b, self.a + self.b return fib# 定义一个main函数,循环遍历每一个菲波那切数def main(): # 20以内的数 fib = Fib(20) for i in fib: print(i)# 测试if __name__ == '__main__': main()
新闻热点
疑难解答