Python Generator 工作机制及应用解析

Python Generator 工作机制及应用解析,第1张

一、Python generator概述及大数据文件读取内存溢出分析

Generators是一类特殊的方法,这类方法返回一个lazy iterator而无需在内存中存储所有的数据内容。Generators是Python的核心内容,对于处理大数据量文件或者数据流(对于流式架构来说,通常有生产者和消费者,数据是一批一批或者一条一条进行处理的,在这种情况下,数据量可以是无限的,你无法预测会有多少数据)并同时需要进行更加精细的控制时是很有用的,在Rasa框架中可以看到基于generators架构的很多应用。

首先看下这种读取文件的方式:

在这个方法中,首先打开一个指定的文件,然后添加每一行数据作为一个元素放入到list中,如果你使用这种方式来统计一个文件中的行数,如果文件内容太大,那么就可能会看到下面的输出:

在这个例子中,方法open()返回一个generator object,正常情况下你可以使用懒加载机制来一行一行读取文件数据,然而如果你使用file.read().split()这种方式,那么就会一次性加载所有数据到内存中,在大数据量的情况下就容易造成MemoryError。

二、如何使用generator来解决大数据文件读取导致的内存溢出问题

在发生内存溢出错误之前,你可能已经发现计算机运行速度变慢了,所以如何处理大数据量的文件呢?下面这个例子改写了上面的方法:

在这个版本中,使用open打开一个文件,然后进行迭代 *** 作,使用yield产出一行,最后可以看到使用这个代码做行数统计的输出效果如下:

上面这个例子就是把csv_reader()转换为一个generator方法,即打开文件后循环遍历每一行,然后产出每一行。使用yield会导致产生一个generator object。你也可以定义一个generator表达式,例如下面的例子,不需要定义一个方法:

你也可以使用generator来生成一个无限的数据序列,譬如下面这个方法:

通过循环调用这个方法来不断生成一个无限的数据序列,除非你主动停止运行它为止:

在这个例子中我们可以看到,在infinite_sequence()这个generator方法内部使用了yield,而yield是在内存中维护了generator的状态结构。如果你不使用for循环,那么也可以使用next()方法。

三、关于generator应用示例

下面开发了一段generator代码,演示如何使用generator逐行读取文件内容。这里使用了一个用于BERT模型训练的数据集CSV文件,文件前3行内容如下:

代码如下:

输出效果如下:

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

原文地址: https://outofmemory.cn/langs/718079.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-25
下一篇 2022-04-25

发表评论

登录后才能评论

评论列表(0条)

保存