执行生成器表达式的最Python方式是什么? [英] What is the most pythonic way to have a generator expression executed?

查看:52
本文介绍了执行生成器表达式的最Python方式是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

越来越多的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情况进行了优化,并且只会消耗可迭代的内容.
我在问题中提到的anyall调用应该同样有效,但是必须担心表达式的真实性才能消耗可迭代项.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆