问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

Python中的“迭代”详解

发布网友 发布时间:2022-09-05 02:23

我来回答

1个回答

热心网友 时间:2023-09-20 13:04

迭代器模式:一种惰性获取数据项的方式,即按需一次获取一个数据项。

所有序列都是可以迭代的。我们接下来要实现一个 Sentence(句子)类,我们向这个类的构造方法传入包含一些文本的字符串,然后可以逐个单词迭代。

接下来测试 Sentence 实例能否迭代

序列可以迭代的原因:

iter()

解释器需要迭代对象 x 时,会自动调用iter(x)。

内置的 iter 函数有以下作用:

由于序列都实现了 __getitem__ 方法,所以都可以迭代。

可迭代对象:使用内置函数 iter() 可以获取迭代器的对象。

与迭代器的关系:Python 从可迭代对象中获取迭代器。

下面用for循环迭代一个字符串,这里字符串 'abc' 是可迭代的对象,用 for 循环迭代时是有生成器,只是 Python 隐藏了。

如果没有 for 语句,使用 while 循环模拟,要写成下面这样:

Python 内部会处理 for 循环和其他迭代上下文(如列表推导,元组拆包等等)中的 StopIteration 异常。

标准的迭代器接口有两个方法:

__next__ :返回下一个可用的元素,如果没有元素了,抛出 StopIteration 异常。

__iter__ :返回 self,以便在需要使用可迭代对象的地方使用迭代器,如 for 循环中。

迭代器:实现了无参数的 __next__ 方法,返回序列中的下一个元素;如果没有元素了,那么抛出 StopIteration 异常。Python 中的迭代器还实现了 __iter__ 方法,因此迭代器也可以迭代。

接下来使用迭代器模式实现 Sentence 类:

注意,不要在 Sentence 类中实现 __next__ 方法,让 Sentence 实例既是可迭代对象,也是自身的迭代器。

为了“支持多种遍历”,必须能从同一个可迭代的实例中获取多个独立的迭代器,而且各个迭代器要能维护自身的内部状态,因此这一模式正确的实现方式是,每次调用 iter(my_iterable) 都新建一个独立的迭代器。

所以总结下来就是:

实现相同功能,但却符合 Python 习惯的方式是,用生成器函数代替 SentenceIteror 类。

只要 Python 函数的定义体中有 yield 关键字,该函数就是生成器函数。调用生成器函数,就会返回一个生成器对象。

生成器函数会创建一个生成器对象,包装生成器函数的定义体,把生成器传给 next(...) 函数时,生成器函数会向前,执行函数定义体中的下一个 yield 语句,返回产出的值,并在函数定义体的当前位置暂停,。最终,函数的定义体返回时,外层的生成器对象会抛出 StopIteration 异常,这一点与迭代器协议一致。

如今这一版 Sentence 类相较之前简短多了,但是还不够慵懒。惰性,是如今人们认为最好的特质。惰性实现是指尽可能延后生成值,这样做能节省内存,或许还能避免做无用的处理。

目前实现的几版 Sentence 类都不具有惰性,因为 __init__ 方法急迫的构建好了文本中的单词列表,然后将其绑定到 self.words 属性上。这样就得处理整个文本,列表使用的内存量可能与文本本身一样多(或许更多,取决于文本中有多少非单词字符)。

re.finditer 函数是 re.findall 函数的惰性版本,返回的是一个生成器,按需生成 re.MatchObject 实例。我们可以使用这个函数来让 Sentence 类变得懒惰,即只在需要时才生成下一个单词。

标准库提供了很多生成器函数,有用于逐行迭代纯文本文件的对象,还有出色的 os.walk 函数等等。本节专注于通用的函数:参数为任意的可迭代对象,返回值是生成器,用于生成选中的、计算出的和重新排列的元素。

第一组是用于过滤的生成器函数:从输入的可迭代对象中产出元素的子集,而且不修改元素本身。这种函数大多数都接受一个断言参数(predicate),这个参数是个布尔函数,有一个参数,会应用到输入中的每个元素上,用于判断元素是否包含在输出中。

以下为这些函数的演示:

第二组是用于映射的生成器函数:在输入的单个/多个可迭代对象中的各个元素上做计算,然后返回结果。

以下为这些函数的用法:

第三组是用于合并的生成器函数,这些函数都可以从输入的多个可迭代对象中产出元素。

以下为演示:

第四组是从一个元素中产出多个值,扩展输入的可迭代对象。

以下为演示:

第五组生成器函数用于产出输入的可迭代对象中的全部元素,不过会以某种方式重新排列。

下面的函数都接受一个可迭代的对象,然后返回单个结果,这种函数叫“归约函数”,“合拢函数”或“累加函数”,其实,这些内置函数都可以用 functools.rece 函数实现,但内置更加方便,而且还有一些优点。

参考教程:
《流畅的python》 P330 - 363

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
十亿韩元折合人民币是多少阿? 邮政银行卡余额查询 邮政储蓄查询余额怎么查 艰难 的国运与雄健的国民读后感500(把以前与现在作对比) 初一下册人教版 艰难的国运与雄健的国民 读后感300字 今日头条哪个版本的有电脑版电脑版今日头条怎么下载 今日头条在电脑上如何安装今日头条怎样就安装到电脑上了 如何评价武庙? 武经总要前集概述 武经总要军事思想 淘宝中怎么删除话费充值记录 乘法定律有哪些 封号了没有电话费了怎么登不上? 滴滴当天不投诉第二天投诉还可以吗 为什么投诉滴滴顺风车司机总显示失败 以前看过一个吸血鬼的电影,是三部曲,里面说吸血鬼是犹大变的。求这个... 1994年腊月26生,一生运气怎样? 1994年腊月二十六,和1995年1月26日同一天到底属啥 我农历94年12月26号出生的,是属猪的吗?是什么星座呢? 农历1994年腊月26应该是属狗还是属猪。 张柏芝气质太高级了,穿白裙优雅大气,状态好的不像中年人 皮肤黑的女生,真的太高级了吧 倪萍的气场太高级了,穿的普普通通也不化妆,却美得很大气 2021下半年的“流行色”太高级了,显白衬肤飙气质,黑黄皮都爱了 合肥师范学院的运动康复专升本好考吗2011年 修改后,我已删除的好友还能再找到我吗? 改了别人还能找到你吗 如果重新注册一个之前的还可以找得回来吗? 朋友的换了,我在用他以前手机搜索不到,还可以搜索到吗? 改了,手机号也改了,还能查到原来的微信吗? 南和县没流水建设银行能贷款吗? Win10怎么激活office? 开车看手机扣分罚款吗 联想yoga售后换键盘价格 lenovo yoga2 键盘一闪一闪不断重启 联想yoga2 13键盘为什么用不了? 二货良品手机租赁手机要还嘛 轻奢乐购商城为什么注册不了收不到验证码注册不了,收不到验证码_百度知... 行货跟水货有什么区别? 小莉帮忙24小时热线电话多少 小莉帮忙收费吗 河南小莉帮忙_百 ... 土豆水煎包怎么做如何做好吃 贵阳卖OPPO手机在哪里? 求贵阳电子数码通讯批发市场的地址。 大家,贵阳最大的二手手机交易市场是在哪里 转正员工自我评价 微众消费是什么 小米手机怎么返修 成都哪里有专业的笔记本贴纸定制 封号了没有电话费了怎么登不上? 21岁男生,脸上粉刺较多,如何去除?