我有一些用例,我需要在不关心产生的项目的情况下运行生成器功能 我不能使它们成为非一般的函数,因为在其他用例中我当然需要产生的值。
我目前正在使用一个简单的自制功能来耗尽发电机。
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())
答案 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)