如何、为什么以及何时-您应该使用Python生成器?

点击上方关注,All in AI中国

如何、为什么以及何时-您应该使用Python生成器?

自从PEP 255引入以来,生成器一直是Python的重要组成部分。

生成器函数允许您声明一个行为类似于迭代器的函数。

它们允许程序员以快速、简单和干净的方式创建迭代器。

你可能会问,什么是迭代器?

迭代器是一个可以迭代(循环)的对象。它用于抽象数据容器,使其行为类似于可迭代对象。您可能已经每天使用一些可迭代对象:字符串、列表和字典等等。

迭代器由实现迭代器协议的类定义。该协议在类中查找两种方法:__iter__和__next__。

为什么你想要制作迭代器?

节省内存空间

迭代器在实例化时不会计算每个项的值。他们只在你要求时计算它。这被称为惰性评估。

当您有一个非常大的数据集要进行计算时,延迟评估很有用。它允许您在计算整个数据集时立即开始使用数据。

假设我们想要得到所有小于最大值的质数。

我们首先定义检查数字是否为素数的函数:

如何、为什么以及何时-您应该使用Python生成器?

然后,我们定义将包含__iter__和__next__methods的迭代器类:

如何、为什么以及何时-您应该使用Python生成器?

Primes以最大值实例化。如果下一个素数大于或等于max,则迭代器将引发StopIteration异常,结束迭代器。

当我们请求迭代器中的下一个元素时,它会将数字增加1并检查它是否为素数。如果不是,它将调用__next__again直到数字为素数。一旦它是,迭代器返回数字。

通过使用迭代器,我们不会在内存中创建素数列表。相反,我们每次请求时都会生成下一个素数。

我们来试试吧:

如何、为什么以及何时-您应该使用Python生成器?

Primes对象的每次迭代都会调用__next__来生成下一个素数。

迭代器只能迭代一次。如果您尝试再次遍历素数,则不会返回任何值。它将表现得像一个空列表。

现在我们知道迭代器是什么以及如何制作迭代器,我们将继续研究生成器。

生成器

回想一下,生成器函数允许我们以更简单的方式创建迭代器。

生成器将yield语句引入Python。它有点像return,因为它返回一个值。

不同之处在于它保存了函数的状态。下次调用该函数时,执行将从它停止的位置继续执行,其变量值与生成前相同。

如果我们将Primes迭代器转换为生成器,它将如下所示:

如何、为什么以及何时-您应该使用Python生成器?

现在这是相当pythonic!我们可以做得更好吗?

是!我们可以使用PEP 289引入的Generator Expressions。

这是生成器的列表理解等价物。它的工作方式与列表推导完全相同,但表达式用()而不是[]包围。

以下表达式可以替换上面的生成器函数:

如何、为什么以及何时-您应该使用Python生成器?

这是Python中生成器的美妙之处。

综上所述...

生成器允许您以非常pythonic的方式创建迭代器。

迭代器允许延迟评估,仅在请求时生成可迭代对象的下一个元素。这对于非常大的数据集很有用。

迭代器和生成器只能迭代一次。

生成器函数优于迭代器。

Generator表达式优于迭代器(仅适用于简单情况)。

如何、为什么以及何时-您应该使用Python生成器?

相关推荐