执行生成器表达式的最Python方式是什么? [英] What is the most pythonic way to have a generator expression executed?
问题描述
越来越多的Python功能逐渐成为惰性可执行文件",例如生成器 表达式和其他类型的迭代器. 但是,有时候,我发现自己想要滚动一个衬里"for"循环,只是为了执行一些操作.
More and more features of Python move to be "lazy executable", like generator expressions and other kind of iterators. Sometimes, however, I see myself wanting to roll a one liner "for" loop, just to perform some action.
要真正使循环真正执行,最蟒蛇的事是什么?
What would be the most pythonic thing to get the loop actually executed?
例如:
a = open("numbers.txt", "w")
(a.write ("%d " % i) for i in xrange(100))
a.close()
不是实际的代码,但是您明白我的意思了.相反,如果我使用列表生成器,则会产生创建填充有无"的N长度列表的副作用.
Not actuall code, but you see what I mean. If I use a list generator, instead, I have the side effect of creating a N-lenght list filled with "None"'s.
当前,我要做的是在调用"any"或"all"时将表达式用作参数.但是我想找到一种不依赖于在循环中执行表达式的结果的方法-"any"和"all"都可以根据所评估的表达式而停止.
Currently what I do is to use the expression as the argument in a call to "any" or to "all". But I would like to find a way that would not depend on the result of the expression performed in the loop - both "any" and "all" can stop depending on the expression evaluated.
要清楚,这些是我已经知道的实现方法,每种方法都有其缺点:
To be clear, these are ways to do it that I already know about, and each one has its drawbacks:
[a.write ("%d " % i) for i in xrange(100))]
any((a.write ("%d " % i) for i in xrange(100)))
for item in (a.write ("%d " % i) for i in xrange(100)): pass
推荐答案
现在是2019年-
这是2010年以来一直存在的一个问题. Python的其中一个邮件列表中的一个最新线程在该主题上发送了70多封电子邮件,他们再次拒绝对该语言添加consume
调用.
It is 2019 -
and this is a question from 2010 that keeps showing up. A recent thread in one of Python's mailing lists spammed over 70 e-mails on this subject, and they refused again to add a consume
call to the language.
在该线程上,实际上显示了该模式下最有效的模式,而且还远远不够明显,因此我将其发布为答案:
On that thread, the most efficient mode to that actually showed up, and it is far from being obvious, so I am posting it as the answer here:
import deque
consume = deque(maxlen=0).extend
然后使用consume
可调用来处理生成器表达式.
And then use the consume
callable to process generator expressions.
事实证明,cPython中的deque
本机代码实际上针对maxlen=0
情况进行了优化,并且只会消耗可迭代的内容.
我在问题中提到的any
和all
调用应该同样有效,但是必须担心表达式的真实性才能消耗可迭代项.
It turns out the deque
native code in cPython actually is optimized for the maxlen=0
case, and will just consume the iterable.
The any
and all
calls I mentioned in the question should be equally as efficient, but one has to worry about the expression truthiness in order for the iterable to be consumed.
我看到这仍然可能是有争议的,毕竟,显式的两行for循环可以处理此问题-我记得这个问题,因为我只是在创建一些线程,然后开始然后联接然后返回的情况下提交了一个- consume
可调用,即4行,大部分为样板,并且没有受益于在本机代码中循环遍历可迭代对象:
https://github.com/jsbueno/extracontext/blob/a5d24be882f9aa18eb19effe3c2cf20c42135ed8/tests/test_thread.py#L27
I see this still may be controversial, after all, an explicit two line for loop can handle this - I remembered this question because I just made a commit where I create some threads, start then, and join then back - without a consume
callable, that is 4 lines with mostly boiler plate, and without benefiting from cycling through the iterable in native code:
https://github.com/jsbueno/extracontext/blob/a5d24be882f9aa18eb19effe3c2cf20c42135ed8/tests/test_thread.py#L27
这篇关于执行生成器表达式的最Python方式是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!