Man*_*áoz 144 python for-loop coding-style
每天我都越来越喜欢python.
今天,我写了一些代码,如:
for i in xrange(N):
do_something()
Run Code Online (Sandbox Code Playgroud)
我不得不做N次.但每次都不依赖于i(索引变量)的值.我意识到我正在创建一个我从未使用过的变量(i),并且我认为"在没有这个无用的索引变量的情况下,确实存在更多的pythonic方式."
所以......问题是:你知道如何以更多(pythonic)美丽的方式完成这个简单的任务吗?
Ale*_*lli 102
比循环更快的方法xrange(N)是:
import itertools
for _ in itertools.repeat(None, N):
do_something()
Run Code Online (Sandbox Code Playgroud)
Gre*_*att 52
正如我在问这个问题时所学到的那样使用_变量,例如:
# A long way to do integer exponentiation
num = 2
power = 3
product = 1
for _ in xrange(power):
product *= num
print product
Run Code Online (Sandbox Code Playgroud)
_与x相同.然而,它是一个python习惯用法,用于表示您不打算使用的标识符.在python中,这些标识符不会像其他语言中的变量一样记忆或分配空间.这很容易忘记.它们只是指向对象的名称,在这种情况下是每次迭代时的整数.
既然功能是一等公民,你可以写小包装(来自Alex答案)
def repeat(f, N):
for _ in itertools.repeat(None, N): f()
Run Code Online (Sandbox Code Playgroud)
那么你可以传递函数作为参数.
小智 5
假设您已将do_something定义为一个函数,并且您想执行N次。也许您可以尝试以下操作:
todos = [do_something] * N
for doit in todos:
doit()
Run Code Online (Sandbox Code Playgroud)
我发现各种答案确实很优雅(尤其是Alex Martelli的答案),但我想直接量化性能,因此我编写了以下脚本:
from itertools import repeat
N = 10000000
def payload(a):
pass
def standard(N):
for x in range(N):
payload(None)
def underscore(N):
for _ in range(N):
payload(None)
def loopiter(N):
for _ in repeat(None, N):
payload(None)
def loopiter2(N):
for _ in map(payload, repeat(None, N)):
pass
if __name__ == '__main__':
import timeit
print("standard: ",timeit.timeit("standard({})".format(N),
setup="from __main__ import standard", number=1))
print("underscore: ",timeit.timeit("underscore({})".format(N),
setup="from __main__ import underscore", number=1))
print("loopiter: ",timeit.timeit("loopiter({})".format(N),
setup="from __main__ import loopiter", number=1))
print("loopiter2: ",timeit.timeit("loopiter2({})".format(N),
setup="from __main__ import loopiter2", number=1))
Run Code Online (Sandbox Code Playgroud)
我还提出了另一种解决方案,该解决方案基于Martelli的解决方案,并用于map()调用有效负载函数。好吧,我有点作弊,因为我可以自由地使有效负载接受被丢弃的参数:我不知道是否有解决方法。但是,结果如下:
standard: 0.8398549720004667
underscore: 0.8413165839992871
loopiter: 0.7110594899968419
loopiter2: 0.5891903560004721
Run Code Online (Sandbox Code Playgroud)
因此使用map可以比loop标准提高30%,比Martelli的标准提高19%。