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

时间:2017-11-23 13:24:01

标签: python python-3.x generator

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

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

def exhaust(generator):
     for _ in generator:
         pass

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

修改 用例:

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)

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

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)

...而在某些情况下,我只想盲目地运行":

exhaust(create_tables())

3 个答案:

答案 0 :(得分:5)

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

您可以将生成器提供给零长度deque;以C速度消耗并且不会像list和其他实现迭代器/生成器的calla那样耗尽内存:

from collections import deque

def exhaust(generator):
    deque(generator, maxlen=0)

取自consume itertools食谱。

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:2)

您可能只有两个函数,每个函数做一件事并在适当的时间调用适当的函数?

def create_table(model, fail_silently=True):
    """Create the table."""
    try:
        model.create_table(fail_silently=fail_silently)
    except Exception:
        return (False, model)
    else:
        return (True, model)

def create_tables(MODELS)
    for model in MODELS:
        create_table(model)
        
def iter_create_tables(MODELS)
   for model in MODELS:
       yield create_table(model)

当您关心返回的值时,请执行以下操作:

for success, table in iter_create_tables(MODELS):
    if success:
        print('Creation of table {} succeeded.'.format(table))
    else:
        print('Creation of table {} failed.'.format(table), file=stderr)

当你不只是做

create_tables(MODELS)