参考博客:Egon
目录
一、迭代器简介
迭代器即用来迭代取值的工具,而迭代是重复反馈过程的活动,其目的通常是为了逼近所需的目标或结果,每一次对过程的重复称为一次“选代”,而每一次选代得到的结果会作为下一次选代的初始值,单纯的重复并不是选代
1.1可迭代对象
通过索引的方式进行选代取值,实现简单,但仅适用于序列类型:字符串,列表,元组。对于没有索引的字典、集合等非序列类型,必须找到一种不依赖索引来进行选代取值的方式,这就用到了选代器。要想了解迭代器为何物,必须事先搞清楚一个很重要的概念:可选代对象(Iterable)。从语法形式上讲,内置有_iter_方法的对象都是可选代对象,字符串、列表、元组、字典、集合、打开的文件都是可选代对象:
{'name':'egon'}.__iter__
{7,8,9}.__iter__
……
1.2迭代器对象
调用obj.iter()方法返回的结果就是一个选代器对象(Iterator)。选代器对象是内置有iter和next方法的对象,打开的文件本身就是一个迭代器对象,执行选代器对象.iter()方法得到的仍然是选代器本身,而执行选代器.next()方法就会计算出选代器中的下一个值。
选代器是Python提供的一种统一的、不依赖于索引的迭代取值方式,只要存在多个"值",无论序列类型还是非序列类型都可以按照选代器的方式取值
>>> s={1,2,3} # 可迭代对象s
>>> i=iter(s) # 本质就是在调用s.__iter__(),返回s的迭代器对象i,
>>> next(i) # 本质就是在调用i.__next__()
1
>>> next(i)
2
>>> next(i)
3
>>> next(i) #抛出StopIteration的异常,代表无值可取,迭代结束
二、for循环的原理
1.基本原理
迭代器的目的是为了让没办法索引的对象也能进行统一的取值!
有了迭代器后,我们便可以不依赖索引选代取值了,使用while循环的实现方式如下(要想使用next操作,必须先用iter把可迭代对象变成迭代器对象)
goods=['mac','lenovo','acer','dell','sony']
i=iter(goods) #每次都需要重新获取一个迭代器对象
while True:
try:
print(next(i))
except StopIteration: #捕捉异常终止循环
break
for循环又称为迭代循环,in后可以跟任意可选代对象,上述while循环可以简写为
goods=['mac','lenovo','acer','dell','sony']
for item in goods:
print(item)
for循环在工作时,首先会调用可选代对象goods内置的iter方法拿到一个选代器对象,然后再调用该迭代器对象的next方法将取到的值赋给item,执行循环体完成一次循环,周而复始,直到捕捉Stoplteration异常,结束迭代。
2.注意一个细节
for循环的in作用的是可迭代对象 ,然后进行把可迭代对象经过两次变形,最后赋值给item(先调用iter,然后调用next赋值),那么,in能不能作用域迭代器对象?
可以
我们要明白一点:虽然c是迭代器对象,in之后还是会调用iter方法,但是最后c还是迭代器对象,所以不影响!
三、迭代器的优缺点
基于索引的选代取值,所有选代的状态都保存在了索引中(一开始就把所有数据加载到内存),而基于选代器实现选代的方式不再需要索引,所有选代的状态就保存在选代器中(一个一个数据的加载,每次只有一个next数据),然而这种处理方式优点与缺点并存:
3.1优点
1、为序列和非序列类型提供了一种统一的选代取值方式。
2、情性计算:选代器对象表示的是一个数据流,可以只在需要时才去调用next来计算出一个值,就选代器本身来说,同一时刻在内存中只有一个值,因而可以存放无限大的数据流,而对于其他容器类型,如列表,需要把所有的元素都存放于内存中,受内存大小的限制,可以存放的值的个数是有限的。
3.2缺点
1、除非取尽,否则无法获取迭代器的长度
2、只能取下一个值,不能回到开始,更像是一次性的,选代器产生后的唯一目标就是重复执行next方法直到值取尽,否则就会停留在某个位置,等待下一次调用next;若是要再次选代同个对象,你只能重新调用iter方法去创建一个新的选代器对象,如果有两个或者多个循环使用同一个选代器,必然只会有一个循环能取到值