迭代器

什么是迭代器
| 迭代是python中访问集合元素的一种非常强大的一种方式。迭代器是一个可以记住遍历位置的对象,因此不会像列表那样一次性全部生成,而是可以等到用的时候才生成,因此节省了大量的内存资源。迭代器对象从集合中的第一个元素开始访问,直到所有的元素被访问完。迭代器有两个方法:iter()和next()方法。 |
可迭代的对象
| 类似于list、tuple、str 等类型的数据可以使用for …… in…… 的循环遍历语法从其中依次拿到数据并进行使用,我们把这个过程称为遍历,也称迭代。python中可迭代的对象有list(列表)、tuple(元组)、str(字符串)set以及对于没有索引的字典、集合等非序列类型也适用。文件直接就是迭代器对象。 |
| a = (1,) |
| b = [1, 2] |
| c = {} |
| d = () |
| s = set() |
| s1 = {None} |
| |
| print(type(c)) |
| print(type(d)) |
| print(type(s)) |
iter()、next()函数 for循环大体过程
iter()获取一个可迭代对象的迭代器
| nums = [1, 2, 3, 4] |
| print(type(nums)) |
| nums_iter = iter(nums) |
| print(type(nums_iter)) |
next()获取迭代器的数据
| nums = [1, 2, 3, 4] |
| nums_iter = iter(nums) |
| num = next(nums_iter) |
| print(num) |
| num = next(nums_iter) |
| print(num) |
for循环大体过程
| for循环的过程可以通过上面的iter()和next()函数来实现,即: |
| 1、先调用iter(),将nums当作实参,得到nums这个可迭代对象的迭代器 |
| 2、调用next(),将上一步得到的迭代器 进行取值 |
| 3、将上一步取出来的值 赋值给num这个变量 |
| 4、执行for循环体中的代码,print(num) |
| 5、重复执行2/3/4步,当nums中所有数据都获取完毕后,会在下一次调用next的时候产生Stopiteration异常。只不过 for循环中自带了异常处理,当它遇到Stopiteration异常的时候,会自动结束for循环 |
自定义"迭代器"
iter 方法
| 迭代器是用来帮助我们记录每次迭代访问到的位置,当我们对迭代器使用 next()函数的时候,迭代器会向我们返回它所记录位置的下一个位置的数据。 |
| 实际上,在使用 next()函数的时候,调用的就是迭代器对象的 next 方法(Python2中是对象的next()方法)。 |
| 所以想要构造一个迭代器,就要实现它的 __next__方法。 |
| 但这还不够,python要求迭代器本身也是可迭代的,所以我们还要为迭代器实现 __iter__方法,而 __iter__方法要返回一个迭代器,迭代器自身正是一个迭代器,所以迭代器的 __iter__方法返回自身即可。 |
| 一个实现了__iter__方法和__next__方法的对象,就是迭代器,可以使用 isinstance() 判断一个对象是否是Iterator对象 |
| from collections import Iterable |
| from collections import Iterator |
| |
| |
| class Classmate(object): |
| """定义一个同学类""" |
| def __init__(self): |
| self.name = list() |
| self.name_num = 0 |
| |
| def add(self,name): |
| self.name.append(name) |
| |
| def __iter__(self): |
| pass |
| |
| def __next__(self): |
| pass |
| |
| class1 = Classmate() |
| class1.add("张三") |
| class1.add("李四") |
| class1.add("王五") |
| |
| print("判断是否是可迭代的对象:", isinstance(class1,Iterable)) |
| print("判断是否是迭代器:", isinstance(class1,Iterator)) |
总结:如果定义类时,有__iter__
方法,那么这个类创建出来的对象一定是可迭代对象
__next__方法
| from collections.abc import Iterable |
| from collections.abc import Iterator |
| |
| class MyList(object): |
| """自定义的一个可迭代对象""" |
| def __init__(self): |
| self.items = [] |
| |
| def add(self, val): |
| self.items.append(val) |
| |
| def __iter__(self): |
| |
| |
| |
| return MyIterator() |
| |
| class MyIterator(object): |
| """自定义的供上面可迭代对象使用的一个迭代器""" |
| def __init__(self): |
| pass |
| |
| def __next__(self): |
| |
| |
| |
| pass |
| |
| def __iter__(self): |
| pass |
| |
| mylist = MyList() |
| mylist_iter = iter(mylist) |
| |
| print("mylist是否是可迭代对象", isinstance(mylist, Iterable)) |
| print("mylist是否是迭代器", isinstance(mylist, Iterator)) |
| |
| print("mylist_iter是否是可迭代对象", isinstance(mylist_iter, Iterable)) |
| print("mylist_iter是否是迭代器", isinstance(mylist_iter, Iterator)) |
| |
| |
总结
| __iter__方法、__next__方法 与 iter()函数、next()函数的区别是, |
| 当对一个可迭代对象调用iter()函数时,它会自动调用这个可迭代对象的__iter__方法,这个方法返回的对象当作迭代器 |
| 当对一个迭代器对象调用 next()函数时,它会自动调用这个迭代器对象的__next__方法,这个方法返回想要那个数据 |
| 迭代器对象 一定是 可迭代对象;可迭代对象不一定是迭代器 |
for…in… 循环的本质
| 1.先调用 iter()函数,它会自动调用可迭代对象中的 __iter__方法,此方法返回这个可迭代对象的 迭代器对象 |
| 2.对获取到的迭代器不断调用 next()函数,它会自动调用迭代器中的 __next__方法来获取下一个值 |
| 3.当遇到 StopIteration异常后循环结束 |
| 并不是只有for循环能接受可迭代对象,除了for循环外,list、tuple等也能接收 |
总结
| 1.凡是可作用于 for循环的对象都是 Iterable 类型; |
| 2.但是可作用于 next()函数的对象都是 Iterator 类型; |
| 3.集合数据类型如 list、dict、str 等是 Iterable 但不是 Iterator, 不过可以通过 iter() 函数获得一个 Iterator 对象 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具