更简单的方法来运行生成器功能而无需关心项目

Ric*_*ann 5 python generator python-3.x

我有一些用例,我需要在不关心产生的项目的情况下运行生成器函数.
我不能使它们成为非齐型函数,因为在其他用例中我当然需要屈服值.

我目前正在使用一个简单的自制功能来耗尽发电机.

def exhaust(generator):
     for _ in generator:
         pass
Run Code Online (Sandbox Code Playgroud)

我想知道,是否有更简单的方法可以做到这一点,我错过了?

编辑 用例:

def create_tables(fail_silently=True):
    """Create the respective tables."""

    for model in MODELS:
        try:
            model.create_table(fail_silently=fail_silently)
        except Exception:
            yield (False, model)
        else:
            yield (True, model)
Run Code Online (Sandbox Code Playgroud)

在某些情况下,我关心错误和成功价值......

for success, table in create_tables():
    if success:
        print('Creation of table {} succeeded.'.format(table))
    else:
        print('Creation of table {} failed.'.format(table), file=stderr)
Run Code Online (Sandbox Code Playgroud)

...而在某些我只是想"盲目地"运行这个功能:

exhaust(create_tables())
Run Code Online (Sandbox Code Playgroud)

Mos*_*oye 6

为此设置for循环可能相对昂贵,请记住Python 中的for循环基本上是简单赋值语句的连续执行; 你将执行n(生成器中的项目数)分配,之后只丢弃分配目标.

您可以将生成器馈送到零长度deque; 以C速度消耗并且不会像使用list实现迭代器/生成器的其他可调用内存那样耗尽内存:

from collections import deque

def exhaust(generator):
    deque(generator, maxlen=0)
Run Code Online (Sandbox Code Playgroud)

取自consumeitertools食谱.

  • @Kos确实,尤其是因为`for _ in generator: pass`不仅没有`deque`解决方案那么神奇,而且还比`deque(generator, maxlen=0)`短一个字符。:-) (4认同)
  • 使用`deque`似乎比OP提出的普通循环要快一点。带有一个Consume.generator函数,该函数会产生前1000个数字,对consumpt.generator()中的_运行`:pass`对我来说每个循环需要71.8 usc,`deque(consume.generator(),maxlen = 0)`花费67.4(根据`timeit`)。 (2认同)
  • 同样,有趣的是,每当有人问“如何以pythonic的方式来做这个简单的事情”时,一切都变成了“如何在每个循环中至少以微秒为单位” (2认同)

mha*_*wke 5

根据您的用例,很难想象会有足够多的表来创建您需要考虑性能。

此外,表创建将比迭代昂贵得多。

所以你已经拥有的 for 循环看起来是最简单和最 Pythonic 的解决方案 - 在这种情况下。


Max*_*Max 5

一种非常简单且可能有效的解决方案可能是

def exhaust(generator): all(generator)
Run Code Online (Sandbox Code Playgroud)

如果我们可以假设它generator总是会返回True(就像在您的情况下,(success,table)即使2 个元素的元组都为真,即使success并且table两者都是False),或者:any(generator)如果它总是会返回False,并且在“最坏的情况”中,all(x or True for x in generator).

如此简短和简单,您甚至可能不需要它的功能!

关于“为什么?” 评论(我不喜欢这些......):在很多情况下,人们可能想要耗尽发电机。仅举一个any(print(i,x) for i,x in enumerate(S))例子,它是一种将 for 循环作为表达式进行处理的方式,例如,-当然还有不那么简单的例子。