迭代器的一些理解
可迭代对象与迭代器
可迭代对象不一定是迭代器,而迭代器一定是可迭代对象.在python中,list序列类型等,通过for...in我们可以遍历其中的数据。我们称其为可迭代对象(iterable)。迭代对象只要实现__iter__()或者__getitem__()即可,迭代器还必须实现__next__()。
from collections.abc import iterable, iterator my_list = [1, 2, 3] my_itorlist = iter(my_list) print(isinstance(my_list, iterator)) print(isinstance(my_itorlist, iterator)) pass
我们可以看到list并不是迭代器类型,iter()函数可以将可迭代对象变为迭代器对象。
将可迭代对象变为迭代器对象后,我们可以通过next()实现顺序访问元素。下图为可迭代对象到迭代器的转换以及访问元素的方法。访问完所有元素后,会抛出stopiteration异常。
my_list = [1,2,3] my_itorlist = iter(my_list) print(next(my_itorlist)) print(next(my_itorlist)) print(next(my_itorlist)) print(next(my_itorlist))
为什么我们需要迭代器?
斐波那契数列指的是这样一个数列:1、1、2、3、5、8、13、21、34。在遇到斐波那契数列需要打印前100个数字的问题,我们最常用的解决办法就是使用如下的while循环。
def fib(index): re_list = [] n,a,b = 0,0,1 while n<index: re_list.append(b) a,b = b, a+b n += 1 return re_list
不可否认这是一个较好的解决办法,但是面对打印海量斐波那契数列的时候,我们就会面对一个内存开销大大增加的问题。我们总不可能把一千万个数据全部存储到列表中吧!这时候迭代器的优点就体现出来了。迭代器只返回下一个数字,并且不会记录上一个数据,在我们需要打印的时候才会计算(惰性计计算)。使用迭代器解决斐波拉契数列的问题,我们即使面对大量的数据,也可以不需要担心内存的占用问题。
class fb: def __init__(self, n): self.n = n #打印的数个数 self.current = 0 self.a = 0 self.b = 1 def __next__(self): if self.current < self.n: """ a=b b=a+b """ self.a, self.b = self.b, self.a + self.b self.current += 1 return self.a else: raise stopiteration def __iter__(self): return self if __name__ == '__main__': fib_print = fb(1000) for num in fib_print: print(num)
自定义迭代器
通过自定义一个迭代器,我们可以更好地理解迭代器到底是个什么东西。
from collections.abc import iterator#导入迭代器的抽象基类 class company(object): def __init__(self, employee_list): self.employee = employee_list def __iter__(self): return levyiterator(self.employee) class levyiterator(iterator):#自定义的迭代器 def __init__(self,employee_list): self.iter_employee = employee_list self.index = 0 def __next__(self): try: next_obj = self.iter_employee[self.index] except indexerror:#捕捉index异常 raise stopiteration#抛出迭代器的异常stopiteration self.index +=1 return next_obj if __name__ == "__main__": company = company(["tom", "bob", "jane"]) my_itor = iter(company) #变为迭代器对象 while true: try: print (next(my_itor)) except stopiteration: break # for item in company: # print(item)
上述代码中,main中的while....break代码是我们迭代输出的部分,这一点其实就是for...in输出的本质:先通过obj.__iter__()将对象变为迭代器类型,然后通过不断的next(obj)输出元素。
上一篇: 花菜上火吗,花菜的价值是什么
下一篇: 中医教你三招搞定湿气