Python中的“迭代”详解

Python中的“迭代”详解,第1张

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

所有序列都是可以迭代的。我们接下来要实现一个 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.reduce 函数实现,但内置更加方便,而且还有一些优点。

参考教程:

《流畅的python》 P330 - 363

有些数据是临时的,它们在应用程序运行时存储在内存中,然后丢弃。但是有些数据是持久的。它们存储在硬盘驱动器上供以后使用,而且它们通常是用户最关心的东西。对于程序员来说,编写代码读写文件是很常见的,但每种语言处理该任务的方式都不同。本文演示了如何使用 Python 处理文件数据。

在 Linux 上,你可能已经安装了 Python。如果没有,你可以通过发行版软件仓库安装它。例如,在 CentOS 或 RHEL 上:

在 macOS 上,你可以使用 MacPorts或Homebrew安装。在 Windows 上,你可以使用Chocolatey安装。

一旦安装了 Python,打开你最喜欢的文本编辑器,准备好写代码吧。

如果你需要向一个文件中写入数据,记住有三个步骤:

这与你在计算机上编码、编辑照片或执行其他 *** 作时使用的步骤完全相同。首先,打开要编辑的文档,然后进行编辑,最后关闭文档。

在 Python 中,过程是这样的:

这个例子中,第一行以 模式打开了一个文件,然后用变量 f 表示,我使用了 f 是因为它在 Python 代码中很常见,使用其他任意有效变量名也能正常工作。

在打开文件时,有不同的模式:

第二行表示向文件中写入数据,本例写入的是纯文本,但你可以写入任意类型的数据。

最后一行关闭了文件。

对于快速的文件交互,常用有一种简短的方法可以写入数据。它不会使文件保持打开状态,所以你不必记得调用 close 函数。相反,它使用 with 语法:

如果你或你的用户需要通过应用程序需要向文件中写入一些数据,然后你需要使用它们,那么你就需要读取文件了。与写入类似,逻辑一样:

同样的,这个逻辑反映了你一开始使用计算机就已知的内容。阅读文档,你可以打开、阅读,然后关闭。在计算机术语中,“打开”文件意味着将其加载到内存中。

实际上,一个文本文件内容肯定不止一行。例如,你需要读取一个配置文件、 游戏 存档或乐队下一首歌曲的歌词,正如你打开一本实体书时,你不可能立刻读完整本书,代码也只能解析已经加载到内存中的文件。因此,你可能需要遍历文件的内容。

示例的第一行指明使用 模式打开一个文件,然后文件交由变量 f 表示,但就像你写数据一样,变量名是任意的。 f 并没有什么特殊的,它只是单词 “file” 的最简表示,所以 Python 程序员会经常使用它。

在第二行,我们使用了 line ,另一个任意变量名,用来表示 f 的每一行。这告诉 Python 逐行迭代文件的内容,并将每一行的内容打印到输出中(在本例中为终端或IDLE)。

就像写入一样,使用 with 语法是一种更简短的方法读取数据。即不需要调用 close 方法,方便地快速交互。

使用 Python 有很多方法向文件写入数据,包括用 JSON、YAML、TOML等不同的格式写入。还有一个非常好的内置方法用于创建和维护SQLite数据库,以及许多库来处理不同的文件格式,包括图像、音频和视频等。

via: https://opensource.com/article/21/7/read-write-files-python

作者:Seth Kenlon选题:lujun9972译者:MjSeven校对:turbokernel

一.什么是迭代器

迭代器是用来迭代取值的工具。

而涉及到把多个值循环取出来的类型有:列表,字符串,元组,字段,集合,打开文件等。通过使用的遍历方式有for···in···,while等,但是,这些方式只适用于有索引的数据类型。为了解决索引取的局限性,python提供了一种 不依赖于索引的取值方式:迭代器

注意:

二.可迭代对象

可迭代对象:但凡内置有__iter__方法的都称为可迭代对象

常见的可迭代对象:

1.集合数据类型,如list,tuple,dict,set,str等

2.生成器,包括生成器和带yield的生成器函数。

三.如何创建迭代器

迭代器是一个包含数个值的对象。

迭代器是可以迭代的对象,这意味着您可以遍历所有值。

从技术上讲,在Python中,迭代器是实现迭代器协议的对象,该协议由方法 __iter__() 和 __next__() 组成。

简而言之,一个类里面实现了__iter__()和__next__()这两个魔法方法,那么这个类的对象就是可迭代对象。

四.迭代器的优缺点

1.优点

2.缺点

五.迭代器示例

另外,如果类Stu继承了Iterator,那么Stu可以不用实现__iter__()方法

遍历迭代器

StopIteration

如果你有足够的 next()语句,或者在 for 循环中使用,则上面的例子将永远进行下去。

为了防止迭代永远进行,我们可以使用 StopIteration语句。

在 __next__()方法中,如果迭代完成指定的次数,我们可以添加一个终止条件来引发错误


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12114984.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存