day4-迭代器
概述
我们经常使用for循环去遍历一些序列数据,但是我们有的时间发现for循环的效率很低,而且很占用了大量的硬件资源,但是有的for循环遍历效率很高,而且很节省硬件资源,这是为什么呢?有人说是生成器的原因。
可迭代对象
1.我们已经知道,可以直接作用于for循环的数据类型有以下几种
- 是集合数据类型,如list,tuple,dict,set,str等
- 是generator,包括生成器和yield的generator function。
2.定义
可以直接作用于for循环的对象统称为可迭代对象:Iterable
3.使用isinstance()判断一个对象是否是Iterable对象
>>> from collections import Iterable #导入Iterable方法 >>> isinstance([],Iterable) #列表 True >>> isinstance((),Iterable) #元组 True >>> isinstance("abc",Iterable) #字符串 True >>> isinstance({}Iterable) #字典 True >>> isinstance((x for x in range(10)),Iterable) #for循环 True >>> isinstance(100,Iterable) False
注意:而生成器不但可以作用于for循环,还可以被__next__()函数不断地调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。
迭代器
1.定义
可以被__next__()函数调用并不断返回下一个值得对象称为迭代器:Iterator
2.可以使用isinstance()判断一个对象是否是Iterator对象:
>>> from collections import Iterator >>> isinstance([],Iterator) #列表 False >>> isinstance((),Iterator) #元组 False >>> isinstance("abc",Iterator) #字符串 False >>> isinstance({},Iterator) #字典 False >>> isinstance((x for x in range(10)),Iterator) #生成器一定是迭代器 True >>> isinstance(100,Iterator) #整型 False
通过上面的例子可以看出,生成器都是Iterator对象,但list,dict,str虽然是可迭代对象(Iterable),却不是迭代器对象(Iterator)
3.iter()函数
用法:把list,dict,str等Iteratable编程Iterator可以使用Iter()函数
>>> a = [1,2,3,4,5,6] >>> iter(a) <list_iterator object at 0x102148da0> >>> b=iter(a) >>> b.__next__() 1 >>> b.__next__() 2
4.你可能会问,为什么list,dict,str等数据类型不是Iterator?
这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被__next__()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过__next__()函数实现按需计算下一个数据,所以Iterator得计算是惰性的,只有在需要返回下一个数据时它才会计算。
注意:Iterator甚至可以表示一个无限大的数据流,例如全体自然数,而使用list是永远不可能存储全体自然数的。
range()方法
在Python3.0中
>>>range(10) range(0,10) #就是一个迭代器
而在Python2.0中
>>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] #返回的是一个list
for I in range(10)
实际上完全等价于:
a=[0,1,2,3,4,5,6,7,8,9] x=iter(a) While True: try: y=next(x) print(y) except StopIteration: break 执行结果: 0 1 2 3 4 5 6 7 8 9
小结
1.for line in f:其实就是使用迭代器去取
2.生成器都是Iterator对象,但list,dict,str虽然是可迭代对象(Iterable),却不是迭代器对象(Iterator)