有没有可能在不创建无用索引变量的情况下完成这个简单的任务,或者采用其他更优雅的方式?怎么做到的?
比在 xrange(N)上循环稍快的方法是:
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)
_ 和 x 是一样的。但是,这是一个 Python 习惯用法,用于指示您不打算使用的标识符。在 python 中,这些标识符不像其他语言中的变量那样接受内存或分配空间。这很容易忘记。它们只是指向对象的名称,在本例中是每次迭代中的一个整数。
然后可以将函数作为参数传递。
我只是使用 for _ in range(n),它直奔主题。它将在 Python2中生成巨大数字的整个列表,但是如果您使用的是 Python3,那么这不是问题。
for _ in range(n)
todos = [do_something] * N for doit in todos: doit()
事实上,我会这样做:
L1是满足条件1的元素的索引列表; (也许您可以使用 somelist.index(condition1)或 np.where(condition1)来获得 L1。)
somelist.index(condition1)
np.where(condition1)
类似地,您得到 L2,一个满足条件2的元素列表;
然后使用 intersect(L1,L2)找到十字路口。
intersect(L1,L2)
我还想出了另一个解决方案,它建立在 Martelli 的解决方案之上,并使用 map()调用有效负载函数。好的,我做了一点小小的欺骗,我自由地让负载接受一个被丢弃的参数: 我不知道是否有办法绕过这个问题。不过,结果如下:
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))
然后可以在任何其他数组中应用索引,例如 x。