Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >你所不知道的Python迭代器

你所不知道的Python迭代器

作者头像
蒙娜丽宁
发布于 2020-04-13 04:49:46
发布于 2020-04-13 04:49:46
40700
代码可运行
举报
文章被收录于专栏:极客起源极客起源
运行总次数:0
代码可运行

迭代就是循环的意思,也就是对一个集合中的元素进行循环,从而得到每一个元素。对于我们自定义的类,也可以让其支持迭代,这就是本文要介绍的特殊成员方法__iter__的作用。用该成员方法可以自定义一个Python迭代器

1 自定义可迭代的类

可能有的读者会问,为什么不使用列表呢?列表可以获取列表的长度,然后使用变量i对列表索引进行循环,不照样可以获取集合的所有元素吗,还容易理解。没错,使用列表的代码是容易理解,也很好操作,但这是要付出代价的。列表之所以可以用索引来快速定位其中的任何一个元素,是因为列表是一下子将所有的数据都装载的内存中了,而且是一块连续的内存空间。如果数据量比较小还好说,如果数据量很大的话,会非常消耗内存资源。而迭代就不同,迭代是读取多少元素,就将多少元素装载到内存中,不读取就不装载。这有点像处理XML的两种方式:DOM和SAX。DOM是一下子将所有的XML数据都装载到内存中,所以可以快速定位任何一个元素,但代价是消耗内存,而SAX是顺序读取XML文档,没读到的XML文档内容是不会装载到内存中的,所以SAX比较节省内存,但只能从前向后顺序读取XML文档的内容。

如果在一个类中定义__iter__方法,那么这个类的实例就是一个迭代器。__iter__方法需要返回一个迭代器,所以就返回对象本身即可(也就是self)。当对象没迭代一次时,就会调用迭代器中的另外一个特殊成员方法__next__。该方法需要返回当前迭代的结果。下面让我们先看一个简单的例子,在这个例子中,通过自定义迭代器对由星号(*)组成的直角三角形的每一行进行迭代,然后通过for循环进行迭代,输出一定行数的直角三角形。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 可无限迭代直角三角形的行class RightTriangle:def __init__(self):    # 定义一个变量n,表示当前的行数        self.n = 1def __next__(self):           # 通过字符串的乘法获取直角三角形每一行的字符串,每一行字符串的长度是2 * n - 1        result = '*' * (2 * self.n - 1)        # 行数加1        self.n += 1        return result    # 该方法必须返回一个迭代器    def __iter__(self):        return selfrt = RightTriangle()# 对迭代器进行迭代for e in rt:     # 限制输出行的长度不能大于20,否则会无限输出行    if len(e) > 20:        break;    print(e)

程序运行结果如下图所示。

2. 将迭代器转换为列表

尽管迭代器很好用,但仍然不具备某些功能,例如,通过索引获取某个元素,进行分片操作。这些操作都是列表的专利,所以在很多时候,需要将迭代器转换为列表。但有很多迭代器都是无限迭代的,就像上一节中的斐波那契数列的迭代。因此,在将迭代器转换为列表时,需要给迭代器能够迭代的元素限定一个范围,否则内存就会溢出了。如果要让迭代器停止迭代,只需要抛出StopIteration异常即可。通过list函数可以直接将迭代器转换为列表。

下面的代码会将斐波那契数列迭代器通过list函数转换为列表。斐波那契数列迭代器限制了最大迭代值不能超过500。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 将迭代器转换为列表class Fibonacci:    def __init__(self):        self.a = 0        self.b = 1    def __next__(self):        result = self.a        self.a, self.b = self.b, self.a + self.b        # 要想让迭代停止,需要抛出StopIteration异常        if result > 500: raise StopIteration        return result    def __iter__(self):        return self fibs1 = Fibonacci()# 将迭代器转换为列表print(list(fibs1))fibs2 = Fibonacci()# 使用for循环对迭代器进行迭代for fib in fibs2:    print(fib, end = ' ')

程序运行结果如图下图所示

从上面的代码可以看出,尽管在__next__方法中,当result大于500时抛出了StopIteration异常,但这个异常是在迭代的过程中由系统处理的,并不会在程序中抛出,所以如果要将无限迭代改成有限迭代,可以在适当的时候抛出StopIteration异常。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-02-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 极客起源 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Python 中的迭代器
自从第4章4.2.6节出现了“可迭代的”(Iterable)一词之后,就不断遇到具有此特征的对象,比如列表、字符串、字典等。判断一个对象是否是可迭代的,主要看它是否具有 __iter__() 方法。
老齐
2021/11/15
1.2K0
python迭代器详解
Python迭代器是Python编程语言中非常常用的一种工具。它是访问容器(例如列表、元组等)中的元素的一种方式,可以逐个访问容器中的元素,而不必将整个容器存储在内存中。
20岁爱吃必胜客
2023/03/26
6620
python迭代器详解
弄懂这 5 个问题,拿下 Python 迭代器!
本篇专题写作思路,由几个问题,逐步讨论迭代器存在的价值、使用的方法、以及如何转化为自身武器并真正用到日常Python中。
龙哥
2020/09/24
4180
弄懂这 5 个问题,拿下 Python 迭代器!
迭代器怎么就节省内存了?
迭代器对象必须要实现两个方法__iter__和__next__,为了帮助大家理解,我们通过自定义一个迭代器加深对它的理解。
double
2020/10/14
1.3K0
【从零学习python 】59.迭代器:优化数据遍历的高效工具
迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
全栈若城
2024/02/29
1500
弄懂这 5 个问题,拿下 Python 迭代器!
本篇专题写作思路,由几个问题,逐步讨论迭代器存在的价值、使用的方法、以及如何转化为自身武器并真正用到日常Python中。
Sam Gor
2020/09/24
3790
弄懂这 5 个问题,拿下 Python 迭代器!
本篇专题写作思路,由几个问题,逐步讨论迭代器存在的价值、使用的方法、以及如何转化为自身武器并真正用到日常Python中。
double
2020/09/23
3880
【Python 第75课】可迭代对象和迭代器
for 循环是我们在 Python 里非常常用的一个语法,但你有没有思考过 for 循环是怎样实现的?
Crossin先生
2019/10/24
7040
迭代器的应用以及说明的问题
但这样存在一个问题,假如列表内的数据量很大,这样还未使用for循环便已经被列表占用很大的资源
py3study
2020/01/17
3170
Python3 | 筑基期, 推导式、迭代器、生成器!
描述:前面,我们一起学习了Python3开发中使用最多的函数(Function),相信大家在作者的实践下也已经掌握函数的创建、多参数的传递,以及匿名函数、闭包了吧,这一章我们一起学习Python3编程中的推导式、迭代器以及生成器等相关知识,它也是Python编程中进阶常用的部分,对于程序健壮性以及效率都有所帮助,所以说也是需要我们掌握的。
全栈工程师修炼指南
2024/07/29
1060
Python3 | 筑基期, 推导式、迭代器、生成器!
Python 迭代器、生成器和列表解析
迭代器在 Python 2.2 版本中被加入, 它为类序列对象提供了一个类序列的接口。 Python 的迭代无缝地支持序列对象, 而且它还允许迭代非序列类型, 包括用户定义的对象。即迭代器可以迭代不是序列但表现出序列行为的对象, 例如字典的 key , 一个文件的行, 等等。迭代器有以下特性:
py3study
2020/01/03
6960
Python __iter__ 深入理解
通过这个斐波那契数列生成器来理解 __iter__。 定义 __iter__ 表示这个类是一个迭代器(iterator)。它只在迭代开始的时候运行一次。返回的是对象本身。这里还给顺手给对象添加了 a 和 b 两个属性。接下来就是循环调用 __next__ 直到遇到 raise StopIteration 为止。调用的过程就是模拟斐波那契数列的过程。
狼啸风云
2021/01/13
6010
Python的迭代器协议
    迭代器是Python中的一个高级概念,迭代器是一个实现了迭代器协议的对象,那何为迭代器协议呢?
py3study
2020/01/09
1.1K2
Python进阶:迭代器与迭代器切片
在前两篇关于 Python 切片的文章中,我们学习了切片的基础用法、高级用法、使用误区,以及自定义对象如何实现切片用法(相关链接见文末)。本文是切片系列的第三篇,主要内容是迭代器切片。
Python猫
2019/04/10
1.7K1
Python进阶:迭代器与迭代器切片
论python中器的组合
python中有几种特殊的对象,如可迭代对象、生成器、迭代器、装饰器等等,特别是生成器这些可以说是python中的门面担当,应用好这些特性的话,可以给我们的项目带来本质上的提升,装逼不说,这构筑的是代码护城河,祖传代码别人再也不敢动。熟悉特性的概念在和面试官交流的过程中也是挺吃香的不是吗?现在这么卷了,面试官也很少会问到迭代啊、递归啊什么的,反过来说,在社招面试被问到了这种看起来挺浅薄的问题,可能就是挂的节奏了:)嘿嘿,真的,毕竟面试是要有相对应的面试时间的,总要有水题来刷时间啊┑( ̄Д  ̄)┍
Yerik
2021/04/25
7350
Python3 迭代器与生成器
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
AlexZhang
2021/12/02
3670
面试题-python 什么是迭代器?
python 里面有 3 大神器:迭代器,生成器,装饰器。在了解迭代器之前,需弄清楚2个概念: 1.什么是迭代 2.什么是可迭代对象
上海-悠悠
2021/03/03
7480
​Python迭代器
我们已经知道可以对 list、tuple、str 等类型的数据使用 for...in... 的循环语法从其中依次拿到数据进行使用,我们把这样的过程称为遍历,也叫迭代。
忆想不到的晖
2021/04/04
5470
探索Python中的迭代器(Iterator)和可迭代对象(Iterable)
在Python编程中,迭代器(Iterator)和可迭代对象(Iterable)是两个重要的概念。它们为我们提供了一种简洁而有效的方式来处理数据集合,同时也是深入理解Python语言内部机制的关键。本文将深入探讨迭代器和可迭代对象的概念、工作原理以及在实际代码中的应用。
疯狂的KK
2023/10/08
4460
探索Python中的迭代器(Iterator)和可迭代对象(Iterable)
迭代器Python_python进阶路线
迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
全栈程序员站长
2022/09/19
2490
相关推荐
Python 中的迭代器
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验