Coding style 不使用索引变量就可以做N次的Python方式?

Coding style 不使用索引变量就可以做N次的Python方式?,coding-style,for-loop,python,Coding Style,For Loop,Python,每天我都越来越喜欢蟒蛇 今天,我写了一些代码,比如: for i in xrange(N): do_something() 我不得不做了N次。但每次都不依赖于i(索引变量)的值。 我意识到我是在创建一个从未使用过的变量(I),我想“肯定有一种更具python风格的方法可以做到这一点,而不需要那个无用的索引变量。” 所以。。。问题是:你知道如何以一种更(pythonic)优美的方式完成这个简单的任务吗?比在xrange(N)上循环稍微快一点的方法是: import itertools

每天我都越来越喜欢蟒蛇

今天,我写了一些代码,比如:

for i in xrange(N):
    do_something()
我不得不做了N次。但每次都不依赖于
i
(索引变量)的值。 我意识到我是在创建一个从未使用过的变量(
I
),我想“肯定有一种更具python风格的方法可以做到这一点,而不需要那个无用的索引变量。”


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

比在
xrange(N)
上循环稍微快一点的方法是:

import itertools

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

使用u变量,正如我在问这个问题时所学到的,例如:

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

这个u和x是一样的。然而,它是一种python习语,用于表示您不打算使用的标识符。在python中,这些标识符不像其他语言中的变量那样占用内存或分配空间。这很容易忘记。它们只是指向对象的名称,在本例中,每次迭代都是一个整数。

因为函数是一级公民,所以可以编写小包装器(来自Alex answers)


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

我只是将
用于范围(n)
中的uu,这是直截了当的。它将在Python2中生成大量数据的完整列表,但是如果您使用Python3,这不是问题。

假设您已经将“做某事”定义为一个函数,并且希望执行它N次。 或许您可以尝试以下方法:

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

简单的while循环怎么样

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

你已经有了变量;为什么不使用它?

我发现各种答案都非常优雅(尤其是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()
调用payload函数。好吧,我有点作弊,因为我自由地让有效负载接受一个被丢弃的参数:我不知道是否有办法解决这个问题。然而,结果如下:

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

因此,使用map比标准for loop提高了约30%,比Martelli多了19%。

快多少?Python3.1还有什么不同吗?@Hamish:我用2.6进行的测试表明速度快了32%(N=1000时为23.2秒,N=1000时为17.6秒)。但无论如何,那真的是一段时间。我会默认使用OP的代码,因为它(对我来说)更容易阅读。了解速度很好。我当然赞同Mike关于OP代码可读性更高的观点。@Wayne,我想这个习惯真的非常强大——除了你已经习惯了这个事实之外,为什么每次执行这个独立于计数的操作时“从0计数到N-1[[完全忽略计数]]从本质上说比“重复N次以下操作”…?你确定速度真的相关吗?如果你在循环中做任何重要的事情,它很可能会花费你选择的迭代方式数百或数千倍的时间吗?@Hamish:几乎没有什么。(在与Alex回答计时相同的条件下,每个循环17.8 us,相差0.2 us)我刚刚了解了变量,但我想你会这样做的。Pythonic,我想我从来没有见过任何一种简单的for循环,至少在Python中。虽然我确信有一些具体的用例,你看着它说“等待,看起来很糟糕”-但是一般来说,XRead是首选方法。(据我所知)。注意事项的可能重复:Python3中不存在xrange。请改用
range
。当然。我们不仅要调用该函数一百万次,还要分配一百万个项目的列表。如果CPU正在工作,内存不也应该有点紧张吗?答案不能确定“没用”(它展示了一种不同的功能性方法),所以我不能投反对票,但我不同意,我完全反对。这不是一个对相同函数值的N个引用的列表吗?最好在itertools中对fn执行
fn()。重复(做点什么,N)
并保存预生成数组…这是我首选的习惯用法。@tzot为什么会有屈尊的语气?这个人会努力写一个答案,现在可能会被劝阻,不愿意在将来做出贡献。即使它对性能有影响,它也是一个可行的选择,特别是当N很小时,性能/内存影响就不会很大重要的是,我总是对Python开发人员对性能的痴迷感到惊讶:)尽管我同意它不是惯用的,而且Python新手阅读它时可能不会像简单使用迭代器时那样清楚地理解正在发生的事情。我唯一的想法是,它是3行代码,而不是1行(?)@AJP-更像是4行与2行的比较(次数>0)和减量(次数-=1)对于开销…比for循环慢得多…@F1Rumors没有测量它,但是如果像PyPy这样的JIT编译器为如此简单的while循环生成较慢的代码,我会感到惊讶。不是downvoter,但可能是因为你在引用另一篇文章,而不是在answer@Downgoat:谢谢你的反馈我提到另一篇文章的目的是指出搜索可能会得到答案。我发现讽刺的是,这个问题的得票数是另一个问题的数倍。
standard:  0.8398549720004667
underscore:  0.8413165839992871
loopiter:  0.7110594899968419
loopiter2:  0.5891903560004721