《编写高质量Python代码的59个有效方法》——第16条:考虑用生成器来改写直接返回列表的函数

简介:

本节书摘来自华章社区《编写高质量Python代码的59个有效方法》一书中的第16条:考虑用生成器来改写直接返回列表的函数,作者[美]布雷特·斯拉特金(Brett Slatkin),更多章节内容可以访问云栖社区“华章社区”公众号查看

第16条:考虑用生成器来改写直接返回列表的函数
如果函数要产生一系列结果,那么最简单的做法就是把这些结果都放在一份列表里,并将其返回给调用者。例如,我们要查出字符串中每个词的首字母,在整个字符串里的位置。下面这段代码,用append方法将这些词的首字母索引添加到result列表中,并在函数结束时将其返回给调用者。

输入一些范例值,以验证该函数能够正常运作:

index_words函数有两个问题。
第一个问题是,这段代码写得有点拥挤。每次找到新的结果,都要调用append方法。但我们真正应该强调的,并不是对result.append方法的调用,而是该方法给列表中添加的那个值,也就是index + 1。另外,函数首尾还各有一行代码用来创建及返回result列表。于是,在函数主体部分的约130个字符(不计空白字符)里,重要的大概只有75个。
这个函数改用生成器(generator)来写会更好。生成器是使用yield表达式的函数。调用生成器函数时,它并不会真的运行,而是会返回迭代器。每次在这个迭代器上面调用内置的next函数时,迭代器会把生成器推进到下一个yield表达式那里。生成器传给yield的每一个值,都会由迭代器返回给调用者。
下面的这个生成器函数,会产生和刚才那个函数相同的效果。

这个函数不需要包含与result列表相交互的那些代码,因而看起来比刚才那种写法清晰许多。原来那个result列表中的元素,现在都分别传给yield表达式了。调用该生成器后所返回的迭代器,可以传给内置的list函数,以将其转换为列表(相关的原理可参见本书第9条)。

index_words的第二个问题是,它在返回前,要先把所有结果都放在列表里面。如果输入量非常大,那么程序就有可能耗尽内存并崩溃。相反,用生成器改写后的版本,则可以应对任意长度的输入数据。
下面定义的这个生成器,会从文件里面依次读入各行内容,然后逐个处理每行中的单词,并产生相应结果。该函数执行时所耗的内存,由单行输入值的最大字符数来界定。

运行这个生成器函数,也能产生和原来相同的效果。

定义这种生成器函数的时候,唯一需要留意的就是:函数返回的那个迭代器,是有状态的,调用者不应该反复使用它(参见本书第17条)。
要点
使用生成器比把收集到的结果放入列表里返回给调用者更加清晰。
由生成器函数所返回的那个迭代器,可以把生成器函数体中,传给yield表达式的那些值,逐次产生出来。
无论输入量有多大,生成器都能产生一系列输出,因为这些输入量和输出量,都不会影响它在执行时所耗的内存。

相关文章
|
29天前
|
存储 算法 调度
【复现】【遗传算法】考虑储能和可再生能源消纳责任制的售电公司购售电策略(Python代码实现)
【复现】【遗传算法】考虑储能和可再生能源消纳责任制的售电公司购售电策略(Python代码实现)
139 26
|
15天前
|
存储 JavaScript Java
(Python基础)新时代语言!一起学习Python吧!(四):dict字典和set类型;切片类型、列表生成式;map和reduce迭代器;filter过滤函数、sorted排序函数;lambda函数
dict字典 Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 我们可以通过声明JS对象一样的方式声明dict
71 1
|
15天前
|
算法 Java Docker
(Python基础)新时代语言!一起学习Python吧!(三):IF条件判断和match匹配;Python中的循环:for...in、while循环;循环操作关键字;Python函数使用方法
IF 条件判断 使用if语句,对条件进行判断 true则执行代码块缩进语句 false则不执行代码块缩进语句,如果有else 或 elif 则进入相应的规则中执行
104 1
|
15天前
|
Java 数据处理 索引
(numpy)Python做数据处理必备框架!(二):ndarray切片的使用与运算;常见的ndarray函数:平方根、正余弦、自然对数、指数、幂等运算;统计函数:方差、均值、极差;比较函数...
ndarray切片 索引从0开始 索引/切片类型 描述/用法 基本索引 通过整数索引直接访问元素。 行/列切片 使用冒号:切片语法选择行或列的子集 连续切片 从起始索引到结束索引按步长切片 使用slice函数 通过slice(start,stop,strp)定义切片规则 布尔索引 通过布尔条件筛选满足条件的元素。支持逻辑运算符 &、|。
78 0
|
18天前
|
测试技术 Python
Python装饰器:为你的代码施展“魔法”
Python装饰器:为你的代码施展“魔法”
199 100
|
18天前
|
开发者 Python
Python列表推导式:一行代码的艺术与力量
Python列表推导式:一行代码的艺术与力量
232 95
|
26天前
|
设计模式 缓存 监控
Python装饰器:优雅增强函数功能
Python装饰器:优雅增强函数功能
236 101
|
26天前
|
Python
Python的简洁之道:5个让代码更优雅的技巧
Python的简洁之道:5个让代码更优雅的技巧
184 104
|
26天前
|
开发者 Python
Python神技:用列表推导式让你的代码更优雅
Python神技:用列表推导式让你的代码更优雅
325 99
|
18天前
|
缓存 Python
Python装饰器:为你的代码施展“魔法
Python装饰器:为你的代码施展“魔法
131 88

热门文章

最新文章

推荐镜像

更多