深入理解Python迭代器和可迭代对象
2018-02-08 11:11
866 查看
1 迭代器
迭代是指对集合元素遍历的一种方式,迭代器是可以实现对集合从前向后依次遍历的一个对象
2 可迭代对象
定义(表面理解)表面来看,只要可以用 for...in...进行遍历的对象就是可迭代对象
自定义可迭代对象(本质)
语法层面,如果一个对象实现了__iter__方法,那么这个对象就是可迭代对象
判断是否是可迭代对象(Iterable)
通过调用Python内置的isinstance来判断是否是Iterable的实例 In [9]: isinstance([],Iterable) Out[9]: True In [10]: isinstance('',Iterable) Out[10]: True In [11]: isinstance({},Iterable) Out[11]: True In [12]: class MyList(object): ....: def __init__(self): ....: self.list = [] ....: def add(self,item): ....: self.list.append(item) ....: In [13]: mylist = MyList() In [14]: isinstance(mylist,Iterable) Out[14]: False
通过上面例子可以看出,Python中的内置类型dict,list,str的对象都是可迭代的,我们自定义了一个类MyList,由于这个类没有实现iter方法,所以这个类的实例不是可迭代对象
接下来实现一个自定义的可迭代对象,只需要给MyList类添加一个iter方法就好。
In [16]: class MyList(object): ....: def __init__(self): ....: self.list = [] ....: def add(self,item): ....: self.list.append(item) ....: def __iter__(self): ....: pass ....: In [17]: from collections import Iterable In [18]: mylist = MyList() In [19]: isinstance(mylist,Iterable) Out[19]: True
至此,我们已经实现了一个自定义的可迭代对象,但是这个可迭代对象还不能通过for…in…语法去迭代,因为我们还缺一个迭代器去帮我们遍历。for…in…遍历的本质就是调用对象的iter方法返回一个迭代器,然后通过这个迭代器去依次取得可迭代对象的每一个元素。Python中的内置可迭代对象用到的迭代器Python已经帮我们实现了,我们自定义的可迭代对象的迭代器只有我们自己动手实现了。
给自定义可迭代对象插上迭代器翅膀
1 from collections import Iterable 2 3 class MyList(object): 4 def __init__(self): 5 self.items = [] 6 7 def add(self,val): 8 self.items.append(val) 9 10 def __iter__(self): 11 12 myiterator = MyIterator(self) 13 return myiterator 14 15 class MyIterator(object): 16 17 def __init__(self,mylist): 18 self.mylist = mylist 19 self.current= 0 20 21 def __next__(self): 22 if self.current < len(self.mylist.items): 23 item = self.mylist.items[self.current] 24 self.current += 1 25 return item 26 else: 27 raise StopIteration 28 def __iter__(self): 29 return self 30 31 if __name__ == '__main__': 34 mylist = MyList() 35 mylist.add(1) 36 mylist.add(2) 37 mylist.add(3) 38 mylist.add(4) 39 mylist.add(5) 40 for num in mylist: 41 print(num)
for…in…遍历mylist时,先通过mylist的iter方法拿到一个迭代器对象myiterator,然后不断调用myiterator的next的方法依次取到遍历的每一个元素。也许会困惑的一点是” MyIterator中的iter方法有什么卵用 ? 里面为什么还要return self, 毕竟我们只需要迭代器的next方法啊!”。其实上面这种写法,完全可以不实现iter这个方法,但是上面例子这种写法在实际项目中是很少见的,通常我们创建一个自定义的可迭代对象不会写两个类这么臃肿,而是写一个类,让这个类既是可迭代对象又是迭代器,此时iter方法需要返回一个迭代器,而自身又是一个迭代器,所以只需要返回自身即可。
将上面两个类优化成一个类
1 class MyList(object): 2 3 def __init__(self): 4 self.items = [] 5 self.current = 0 6 7 def add(self,val): 8 self.items.append(val) 9 10 def __next__(self): 11 if self.current < len(self.items): 12 item = self.items[self.current] 13 self.current += 1 14 return item 15 else: 16 raise StopIteration 17 18 def __iter__(self): 19 return self #可迭代对象本身就是一个迭代器 20 21 if __name__ == '__main__': 22 mylist = MyList() 23 mylist.add(1) 24 mylist.add(2) 25 mylist.add(3) 26 mylist.add(4) 27 mylist.add(5) 28 for num in mylist: 29 print(num)
3. 迭代器(可迭代对象)的应用
因为通常可迭代对象本身就是一个迭代器,所以二者的用途一般是一致的。我们发现迭代器的本质就是通过next()函数(next本质是调用迭代器的_next方法)不断得到下一个数据,假如需要遍历的数据是可以通过计算规则依次得到的,这时候通过迭代器(升级版本是生成器)去遍历就会避免传统遍历需要依赖已有数据集合从而需要占用大量内存的弊端。下面通过一个经典例子求斐波那契数列的前n项来说明迭代器的优势。斐波那契数列
数列中第一个数为0,第二个数为1,其后的每一个数都是前两个数相加之和: 0,1,1,2,3,5,8,13,21,34...
通过迭代器实现输出前n项的代码:
1 #coding:utf-8 2 class FibIterator(object): 3 def __init__(self,n): 4 self.n = n #需要遍历的元素个数 5 self.current = 0 #当前遍历的元素个数 6 self.num1 = 0 #第一个元素 7 self.num2 = 1 #第二个元素 8 9 def __next__(self): 10 if self.current < self.n: 11 self.num1, self.num2 = self.num2, self.num1+self.num2 12 self.current+=1 13 return self.num1 14 else: 15 raise StopIteration 16 17 def __iter__(self): 18 return self 19 20 if __name__ == '__main__': 21 fibiterator = FibIterator(10) 22 for num in fibiterator: 23 print(num)
可以看出遍历的元素是通过即时运算生成的,而没有事先占用任何存储空间。迭代器和可迭代对象的知识到这里差不多已经全介绍完了,下篇将会分析Python另一个比较重要的知识点生成器。
相关文章推荐
- python学习笔记--可迭代对象和迭代器的理解
- 完全理解Python迭代对象、迭代器、生成器
- 完全理解 Python 迭代对象、迭代器、生成器
- 【python】14、完全理解可迭代对象、迭代器、生成器
- 理解Python迭代对象、迭代器、生成器
- 完全理解Python迭代对象、迭代器、生成器
- 迭代器就是重复地做一些事情,可以简单的理解为循环,在python中实现了__iter__方法的对象是可迭代的,实现了next()方法的对象是迭代器,这样说起来有
- 完全理解 Python 迭代对象、迭代器、生成器
- 完全理解Python迭代对象、迭代器、生成器
- 完全理解 Python 迭代对象、迭代器、生成器
- 完全理解Python迭代对象、迭代器、生成器
- 完全理解 Python 迭代对象、迭代器、生成器
- 完全理解PYTHON迭代对象、迭代器、生成器
- Python中可迭代对象和迭代器对象的理解
- 完全理解 Python 迭代对象、迭代器、生成器
- 完全理解 Python 迭代对象、迭代器、生成器
- Python 可迭代的对象、迭代器和生成器
- python 3-1 如何实现可迭代对象iterable和迭代器对象iterator,__iter__,__getitem__
- Python迭代对象、迭代器、生成器
- 可迭代对象、迭代器、生成器的理解