pythonic方式做N次而没有索引变量?

时间:2010-06-04 00:39:15

标签: coding-style for-loop python

每天我都越来越喜欢python。

今天,我写了一些代码:

for i in xrange(N):
    do_something()

我必须做N次。但每次都不依赖于i(索引变量)的值。 我意识到我正在创建一个我从未使用过的变量(i),并且我认为“在没有这个无用的索引变量的情况下,确实存在更多的pythonic方式。”

所以...问题是:你知道如何以更多(pythonic)美丽的方式完成这个简单的任务吗?

8 个答案:

答案 0 :(得分:98)

xrange(N)上的循环更快的方法是:

import itertools

for _ in itertools.repeat(None, N):
    do_something()

答案 1 :(得分:48)

使用_变量,就像我在问question时所学到的那样,例如:

# A long way to do integer exponentiation
num = 2
power = 3
product = 1
for _ in xrange(power):
    product *= num
print product

答案 2 :(得分:31)

我只是使用for _ in range(n),这是直截了当的。它将在Python 2中为大量数据生成整个列表,但如果您使用的是Python 3则不是问题。

答案 3 :(得分:9)

由于函数是一等公民,你可以写小包装(来自Alex答案)

def repeat(f, N):
    for _ in itertools.repeat(None, N): f()

然后你可以传递函数作为参数。

答案 4 :(得分:8)

_与x相同。然而,它是一个python习惯用法,用于表示您不打算使用的标识符。在python中,这些标识符不会像其他语言中的变量一样记忆或分配空间。这很容易忘记。它们只是指向对象的名称,在这种情况下是每次迭代时的整数。

答案 5 :(得分:4)

假设您已将 do_something 定义为函数,并且您希望执行 N 次。 也许您可以尝试以下方法:

todos = [do_something] * N  
for doit in todos:  
    doit()

答案 6 :(得分:4)

我发现各种答案非常优雅(特别是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))

我还提出了一个替代解决方案,它基于Martelli的解决方案并使用map()来调用有效负载功能。好吧,我作弊了一点,因为我自由地使有效载荷接受一个被丢弃的参数:我不知道是否有办法解决这个问题。不过,结果如下:

standard:  0.8398549720004667
underscore:  0.8413165839992871
loopiter:  0.7110594899968419
loopiter2:  0.5891903560004721

所以使用map比标准for循环产生大约30%的改进,比Martelli的产生额外19%。

答案 7 :(得分:0)

简单的while循环怎么样?

while times > 0:
    do_something()
    times -= 1

你已经拥有变量;为什么不用呢?