jsb*_*eno 3 python generator lazy-evaluation
Python的越来越多的特性变成了"懒惰的可执行文件",比如生成器表达式和其他类型的迭代器.然而,有时候,我发现自己想要推出一个"for"循环,只是为了执行一些动作.
让循环实际执行的最pythonic是什么?
例如:
a = open("numbers.txt", "w")
(a.write ("%d " % i) for i in xrange(100))
a.close()
Run Code Online (Sandbox Code Playgroud)
不是代码,但你明白我的意思.如果我使用列表生成器,相反,我有副作用创建一个填充"无"的N长度列表.
目前我所做的是在调用"any"或"all"时使用表达式作为参数.但是我想找到一种不依赖于循环中执行的表达式结果的方法 - "any"和"all"都可以根据所评估的表达式停止.
要清楚,这些是我已经知道的方法,每个都有它的缺点:
[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
Run Code Online (Sandbox Code Playgroud)
Jer*_*rub 10
有一种明显的方法可以做到这一点,这就是你应该这样做的方式.没有任何借口可以巧妙地做到这一点.
a = open("numbers.txt", "w")
for i in xrange(100):
a.write("%d " % i)
d.close()
Run Code Online (Sandbox Code Playgroud)
延迟执行为您带来了一个重要的好处:它允许您将序列传递给另一段代码而无需将整个内容保存在内存中.它用于创建有效序列作为数据类型.
在这种情况下,您不希望延迟执行.你想要执行.你可以......执行.带for循环.
如果我想做这个具体的例子,我会写
for i in xrange(100): a.write('%d ' % i)
Run Code Online (Sandbox Code Playgroud)
如果我经常需要使用迭代器来实现其效果,我会定义
def for_effect(iterable):
for _ in iterable:
pass
Run Code Online (Sandbox Code Playgroud)
有很多accumulators具有消费整个迭代的效果他们给出的,如min或max-但即使他们不完全忽视在这个过程中所产生的结果(min和max,例如,如果将一些的抛出一个异常结果很复杂).我不认为有一个内置的累加器可以完全按照你想要的 - 你必须编写(并添加到你的微型实用功能的个人藏匿处)一个微小的实用功能,如
def consume(iterable):
for item in iterable: pass
Run Code Online (Sandbox Code Playgroud)
我想,主要原因是Python有一个for声明,你应该在它像手套一样使用它时(例如,对于你想要的情况consume;-).
a.write返回,返回None,这是假的,所以any实际上会消耗它(并且a.writelines会做得更好!).但我意识到你只是把它作为一个例子;-).