没有索引变量的 pythonic 方法来做 N 次?

有没有可能在不创建无用索引变量的情况下完成这个简单的任务,或者采用其他更优雅的方式?怎么做到的?

150850 次浏览

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

import itertools


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

使用 _变量,如下所示:

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

使用 _变量,如下所示:

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

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

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

我只是使用 for _ in range(n),它直奔主题。它将在 Python2中生成巨大数字的整个列表,但是如果您使用的是 Python3,那么这不是问题。

我只是使用 for _ in range(n),它直奔主题。它将在 Python2中生成巨大数字的整个列表,但是如果您使用的是 Python3,那么这不是问题。

也许你可以试试以下方法:

todos = [do_something] * N
for doit in todos:
doit()
Print (“ underscore:”,timeit.timeit (“ underscore ({})”. format (N) ,

事实上,我会这样做:

Setup = “ from _ _ main _ _ import underscore”,number = 1))

L1是满足条件1的元素的索引列表; (也许您可以使用 somelist.index(condition1)np.where(condition1)来获得 L1。)

Print (“ loop iter:”,timeit.timeit (“ loop iter ({})”. format (N) ,

类似地,您得到 L2,一个满足条件2的元素列表;

Setup = “ from _ _ main _ _ import loop iter”,number = 1)) Print (“ loop iter2:”,timeit.timeit (“ loop iter2({})”. format (N) , Setup = “ from _ _ main _ _ import loop iter2”,number = 1))

然后使用 intersect(L1,L2)找到十字路口。

我还想出了另一个解决方案,它建立在 Martelli 的解决方案之上,并使用 map()调用有效负载函数。好的,我做了一点小小的欺骗,我自由地让负载接受一个被丢弃的参数: 我不知道是否有办法绕过这个问题。不过,结果如下:

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

所以使用 map 比标准 for 循环提高了大约30% ,比 Martelli 的提高了19% 。

如果要满足多个条件,还可以找到多个列表的交集。

我发现各种答案都非常优雅(尤其是亚历克斯•马特利(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

然后可以在任何其他数组中应用索引,例如 x。

所以使用 map 比标准 for 循环提高了大约30% ,比 Martelli 的提高了19% 。