前往小程序,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 删除。

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Vue组件开发三板斧:prop、event、slot
组件,有些可以完全独立运行完全不依赖外部属性,比如层级较高的页面组件。但大多时候,组件还是需要使用方做一些定制操作,并可以在状态变化时通知给使用方,于是,一个组件最基本的API就是prop、event、slot,只要了解它们,那么再复杂的功能也能够做出来。
娜姐
2020/09/22
2.1K0
【愚公系列】《AIGC辅助软件开发》016-AI辅助前端编程:利用ChatGPT在前端开发中快速生成Vue组件
文章地址:https://cloud.tencent.com/developer/article/2474495
愚公搬代码
2024/12/08
1800
vue中父子组件传递信息实现
在父组件的script中通过import引入,然后通过components进行挂载,最后以标签的形式使用
wfaceboss
2019/04/08
6300
vue组件通信方式有哪些?1
父组件通过props的方式向子组件传递数据,而通过$emit 子组件可以向父组件通信。
bb_xiaxia1998
2023/01/03
1.7K0
腾讯二面vue面试题总结
对象内部通过 defineReactive 方法,使用 Object.defineProperty 来劫持各个属性的 setter、getter(只会劫持已经存在的属性),数组则是通过重写数组7个方法来实现。当页面使用对应属性时,每个属性都拥有自己的 dep 属性,存放他所依赖的 watcher(依赖收集),当属性变化后会通知自己对应的 watcher 去更新(派发更新)
bb_xiaxia1998
2022/11/18
7530
Vue学习-组件化开发
将一个页面拆分成一个个小的功能块,每个功能块完成自己独立的功能,这样在之后的页面维护和管理就会方便许多。
花猪
2022/02/17
1.5K0
Vue学习-组件化开发
vue父组件引入子组件_vue子组件传递方法给父组件
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/09
1.1K0
Vue 05.组件
组件: 组件是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可; 组件化和模块化区别:
LittlePanger
2020/04/14
9640
Vue 父子组件传值以及父调子方法和子调父方法
在 Vue.js 中,组件通信是一个至关重要的概念。父子组件之间的数据传递和方法调用是常见的需求,它们构建了一个强大的交互体验。
一个正经的程序员
2023/08/30
3.4K0
Vue 父子组件传值以及父调子方法和子调父方法
Vue传值与状态管理总结
使用prop使得父子组件形成一个单向下行绑定:一般情况下,父级prop的更新会流动到子组件中,但是反过来则不行;
前端老道
2022/03/29
2.2K0
Vue子组件调用父组件的方法及传值「建议收藏」
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/11
1.2K0
Vue.js组件设计模式:构建可复用组件库
在Vue.js中,构建可复用的组件库是提高代码复用性和维护性的关键。下面是一些设计模式示例,说明如何创建可复用的Vue组件:
天涯学馆
2024/08/20
1670
Vue 组件数据通信方案总结
初识 Vue.js ,了解到组件是 Vue 的主要构成部分,但组件内部的作用域是相对独立的部分,组件之间的关系一般如下图:
前端迷
2019/09/25
4480
Vue 组件数据通信方案总结
Vue.js——组件快速入门(下篇)
上一篇我们重点介绍了组件的创建、注册和使用,熟练这几个步骤将有助于深入组件的开发。
Vincent-yuan
2020/07/08
10.1K0
Vue.js——组件快速入门(下篇)
Vue 组件与组件间的交互
此时,父子组件都进行了更改,name显示的值均为 “李四” ,巧妙的使用 JS 引用类型,
White feathe
2021/12/08
1.9K0
Vue 组件与组件间的交互
用vue实现模态框组件
基本上每个项目都需要用到模态框组件,由于在最近的项目中,alert组件和confirm是两套完全不一样的设计,所以我将他们分成了两个组件,本文主要讨论的是confirm组件的实现。 组件结构 <tem
对角另一面
2017/12/27
3.6K0
组件化详细
最终效果: 必须是当前组件的元素, 才会有这个自定义属性, 才会被这个样式作用到
用户11097514
2024/05/31
2240
组件化详细
Vue 组件通信的 8 种方式
[3245a3c0598b4b79b32f60649ded9cca~tplv-k3u1fbpfcp-watermark.image] 前言     做了半年的公司系统,终于就在前天上线了。后期改BUG时间拖得太长了,出现的大部分BUG 是 前端 与后端 信息不对称导致的,逻辑性错误很不多,用户体验上稍微差点,毕竟第一次做这么大的系统(100w+),通过这次系统的开发,总结了不少经验,如何更好的跟后端人员协作开发以及如何设计来提高用户体验上,之前自己做开发没关注这方面,只注重功能实现,后期的这块多补补。
程序员海军
2022/02/15
3790
Vue 组件通信的 8 种方式
Vue把父组件的方法传递给子组件调用(评论列表例子)
Vue把父组件的方法传递给子组件调用(评论列表例子) 效果展示: image 相关Html: <!DOCTYPE html> <html lang="en"> <head> <meta cha
Dream城堡
2018/12/06
1.7K0
elementUI中el-tabs或者说Vue现存的一个bug排查
在 el-dialog 中使用 el-tabs ,并且 el-dialog 添加 destroy-on-close 属性,当关闭弹窗的时候页面就直接无响应了。
windliang
2022/09/23
1.4K0
elementUI中el-tabs或者说Vue现存的一个bug排查
相关推荐
Vue组件开发三板斧:prop、event、slot
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验