可迭代对象和迭代器
https://blog.csdn.net/nightcharm/article/details/78964676
可迭代对象
对象里面含有__iter__()方法的实现,对象的__iter__()函数经调用后会返回一个迭代器,这个迭代器含有具体数据获取的实现。
迭代器
包含__next__()方法的实现,在正确范围内返回下一个可用元素;超出范围后抛出StopIteration,通知调用者迭代结束。
迭代器工作的基本步骤
https://blog.csdn.net/bluebird_237/article/details/38894617
1. 可迭代对象调用 __iter__()方法返回迭代器(self)
2. 迭代器调用__next()__ 函数,返回下一个可用元素;如果没有元素了,抛出StopIteration
for... in...的实现原理
如果一个类想被用于for ... in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的next()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。
我们以斐波那契数列为例,写一个Fib类,可以作用于for循环
1 class Fib(object): 2 def __init__(self): 3 self.a, self.b = 0, 1 4 5 def __iter__(self): 6 return self 7 8 def __next__(self): 9 self.a, self.b = self.b, self.a + self.b 10 if self.a > 1000: 11 raise StopIteration(); 12 return self.a 13 14 for n in Fib(): 15 print(n) 16 17 18 # 1 19 # 2 20 # 3 21 # 5 22 # 8 23 # 13 24 # 21 25 # 34 26 # 55 27 # 89 28 # 144 29 # 233 30 # 377 31 # 610 32 # 987
注意:在python 3中应使用__next__(), 而非 next(), 否则会报错:TypeError: iter() returned non-iterator of type 'Fib'。
实现的大致流程:
1 for i in seq: 2 do_sth_to(i) 3 4 ################ 5 6 fetch = iter(seq) #return an iterator 7 while True: 8 try: 9 i = fetch.next() # iterator call __next__() 10 except StopIteration: 11 break # iteration finished 12 do_sth_to(i)
迭代器的工作原理
迭代器相当于一个有__next__()方法的对象,当(一个循环机制)需要下一项时,调用迭代器的__next__()方法即可获得。条目全部被取出后,会引发一个StopIteration异常,通知外部调用者,迭代完成。
迭代器的限制
1. 不能向后移动回到开始
2. 不能复制一个迭代器
3. 若要再次(或同时)迭代同个对象,只能去创建另一个迭代器对象
4. 迭代时请尽量不要修改该对象,否则可能会出错
其他工具:
1. reversed()内建函数将返回一个反序访问的迭代器
2. enumerate()内建函数返回迭代器
3. any(), all()
4. python提供itertools 模块, 它包含各种有用的迭代器
对比生成器
迭代器是一个对象,生成器是一个函数。
迭代器和生成器是python中两个非常强大的特性,编写程序时你可以不使用生成器达到同样的效果,但是生成器让你的程序更加pythonic。
创建生成器非常简单,只要在函数中加入yield语句即可。函数中每次使用yield产生一个值,函数就返回该值,然后停止执行,等待被激活,被激活后继续在原来的位置执行。
1 def fib(): 2 a, b = 0, 1 3 while 1: 4 a, b = b, a + b 5 yield a 6 7 for f in fib(): 8 if f < 1000: 9 print(f) 10 else: 11 break