在方法中考虑返回生成器而不是返回列表

方法返回一个序列的最简单方式就是返回列表,例如想要返回一个句子中全部单词的位置,下面的代码通过使用列表来保存单词的位置并在方法执行结束返回列表:

在方法中考虑返回生成器而不是返回列表

上面方法的简单调用:

在方法中考虑返回生成器而不是返回列表

虽然对于这类简单应用不会有任何问题,但是index_words方法还是有两个问题:

  • 首先,代码有点丑。。。每次发现一个新的结果时,都需要调用append方法。result.append又需要对结果进行计算(index + 1)。需要一行代码去计算结果,再需要一行代码去返回结果。无用代码太多了。

解决办法就是使用生成器。生成器就是使用yield的方法。每次调用next方法时,迭代器(iterator)都会在生成器中前进一步。每一个生成器传递给yield的值都会通过迭代器返回给调用者。

下面使用生成器重写以上代码:

在方法中考虑返回生成器而不是返回列表

此时代码看起来就清晰多了,因为代码中没有过多额外的计算工作了。结果都被直接传递给了yield。使用list方法可以很方便的把上面方法返回的迭代器传换成一个数组。

在方法中考虑返回生成器而不是返回列表

  • 第二个问题也是我们以前常常提到的问题,使用数组作为返回值的话需要在返回结果前计算出所有结果值。如果数据量太大就会导致内存不足。与此对比,生成器就不会占用太多内存了。

下面我写了一个新方法,这个方法每次从文件中读取一行数据,然后每次返回这一行中的一个单词。这个方法运行时所占用的最大内存取决于最大行的长度。

在方法中考虑返回生成器而不是返回列表

运行以上代码:

在方法中考虑返回生成器而不是返回列表

使用生成器需要注意的一点就是,返回结果是有状态的,不能重复使用。

注意事项:

  • 使用生成器比直接返回数组更清晰;
  • 生成器可以接收任意长度的输入值。


分享到:


相關文章: