【python】基础之迭代器
-
1.总览
-
2.迭代器介绍
- 2.1:迭代器是一个实现了迭代协议的对象,它可以让我们遍历一个容器中的所有元素,而不需要知道容器的内部结构,迭代器可以用于遍历列表,元祖,字典,集合等容器类型;
- 2.2:迭代器的工作原理是通过实现两个方法:iter()和__next__()方法,iter()方法返回迭代器对象本身,next()方法每次调用都会返回容器中的下一个元素,直到容器中的所有元素都被遍历完毕后,再调用__next__()方法就会抛出Stopiteration异常;
-
3.for循环底层原理
# 可迭代对象 === 容器
list01 = [11,22,33,44]
# 迭代过程
# for item in list01:
# print(item)
# 迭代原理
# 面试题:for循环的原理是什么?
# 可以被for的条件时什么?
# 答:必须具备__iter__方法
# 1.获取迭代器
iterator = list01.__iter__()
# 2.循环获取每一个元素
while True:
try:
item = iterator.__next__()
print(item)
# 3.遇到异常停止迭代
except StopIteration:
break
-
3.1:可以直接用作for循环的数据类型有:1、集合数据类型,如list,tuple,dict,set,str等;2、generator,包含生成器和带yeild的generator方法。这些用作for循环的对象统称为可迭代对象:iterable;而可以被next()函数调用并且不断返回下一个值的对象称为迭代器:iterator。
-
3.2:list,dict,str等虽然是iterable,却不是iterator
注:为什么list,dict,str等数据类型不是iterator?因为python的iterator对象表示的是一个数据流,iterator对象可以被next函数调用并且不断返回下一个数据,直到没有数据抛出Stopiteration错误,可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能通过next函数实现下一个数据,所以iterator的计算是惰性的。 -
4.自定义迭代器
"""
迭代器:
"""
class Skill:
pass
class SkillIterator:
def __init__(self,target):
self.__target = target
self.__index = 0
def __next__(self):
# 如果没有数据了,抛出异常
if self.__index > len(self.__target)-1:
raise StopIteration
# 返回下一个数据
temp = self.__target[self.__index]
self.__index += 1
return temp
class SkillManger:
def __init__(self):
self.__skills = []
def add_skill(self,skill):
self.__skills.append(skill)
def __iter__(self):
# 创建一个迭代器对象,并传递需要被迭代的数据
return SkillIterator(self.__skills)
manger = SkillManger()
manger.add_skill(Skill())
manger.add_skill(Skill())
manger.add_skill(Skill())
# for item in manger:
# print(item)
iterator = manger.__iter__()
while True:
try:
item = iterator.__next__()
print(item)
except StopIteration:
break
- 5.迭代器的优缺点
- 优点
- 为序列和非序列类型提供了一种统一的迭代取值方式。
- 惰性计算:
- 迭代器对象表示的是一个数据流,可以只在需要时才去调用next来计算出一个值
- 就迭代器本身来说,同一时刻在内存中只有一个值,因而可以存放无限大的数据流,
- 而对于其他容器类型,如列表,需要把所有的元素都存放于内存中,受内存大小的限制,可以存放的值的个数是有限的。
- 缺点
- 除非取尽,否则无法获取迭代器的长度
- 只能取下一个值,不能回到开始,更像是‘一次性的’,迭代器产生后的唯一目标就是重复执行next方法直到值取尽,否则就会停留在某个位置,等待下一次调用next;
- 若是要再次迭代同个对象,你只能重新调用iter方法去创建一个新的迭代器对象,如果有两个或者多个循环使用同一个迭代器,必然只会有一个循环能取到值。
- 优点