append函数_高质量python代码:考虑用生成器来改写直接返回列表的函数

写在前面:内容参照自《Effective Python》,其实你完全可以直接去看书,什么?你不想自己看书,那么你也可以关注我,我会不定期从书中挑出常用到的有效方法分享出来,这样你就可以一边刷头条,一边学习知识,岂不美哉。

正文

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

154f10dcce6b65a7be27ca4fd42ce159.png

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

f67618170d7b6c9da362eec23992431c.png

上面的 index_words 函数有两个问题。

第一个问题是,这段代码写得有点拥挤。每次找到新的结果,都要调用 append 方法。但我们真正应该强调的,并不是对 result.append 方法的调用,而是该方法给列表中添加的那个值,也就是 index+1。另外,函数首尾还各有一行代码用来创建及返回 result 列表。于是,在函数主体部分的约 130 个字符(不计空白字符)里,重要的大概只有 75 个。

这个函数改用生成器(generator)来写会更好。生成器是使用 yield 表达式的函数。调用生成器函数时,它并不会真的运行,而是会返回迭代器。每次在这个迭代器上面调用内置的 next 函数时,迭代器会把生成器推进到下一个 yield 表达式那里。生成器传给 yield 的每一个值,都会由迭代器返回给调用者。

下面的这个生成器函数,会产生和刚才那个函数相同的效果:

67452b5c1f89e61256837dc39c0c4ebb.png

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

36ede6cd377e95655f4430cc6ad061fb.png

index_words 函数的第二个问题是,它在返回前,要先把所有结果都放在列表里面。如果输入量非常大,那么程序就有可能耗尽内存并崩溃。相反,用生成器改写后的版本,则可以应对任意长度的输入数据。

下面定义的这个生成器,会从文件里面依次读入各行内容,然后逐个处理每行中的单词,并产生相应结果。该函数执行时所耗的内存,由单行输入值的最大字符数来界定。

4e2406d3e6f3713e2641f5967cfffc8e.png

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

655421b206d72622db160542b00a28ff.png

要点

  • 使用生成器比把收集到的结果放入列表里返回给调用者更加清晰。
  • 由生成器函数所返回的那个选代器,可以把生成器函数体中,传给 yield 表达式的那些值,逐次产生出来。
  • 无论输入量有多大,生成器都能产生一系列输出,因为这些输入量和输出量,都不会影响它在执行时所耗的内存。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值