我有这段代码:
def iterate_through_list_1(arr):
lala = None
for i in range(len(arr))[::-1]:
lala = i
def iterate_through_list_2(arr):
lala = None
for i in range(len(arr), 0, -1):
lala = i
逻辑上,以相反的顺序迭代range()
创建的列表应该比使用range()
创建列表并随后使用[::-1]
将其反转更有效。但是 cProfile 告诉我,iterate_through_list_1
函数运行得更快。
我使用的是python-3。在这里,您可以看到两个相同数组的分析输出,其中包含100000000个元素。
ncalls tottime percall cumtime percall filename:lineno(function)
1 5.029 5.029 5.029 5.029 bs.py:24(iterate_throgh_list_2)
1 4.842 4.842 4.842 4.842 bs.py:19(iterate_throgh_list_1)
创建列表时Python切片下面发生了什么?
答案 0 :(得分:1)
设计良好的测试显示Python 2.x上的第一个函数最慢(主要是因为必须创建两个列表,第一个作为增加范围,第二个作为恢复的第一个)。我还使用reversed
包含了一个演示。
from __future__ import print_function
import sys
import timeit
def iterate_through_list_1(arr):
lala = None
for i in range(len(arr))[::-1]:
lala = i
def iterate_through_list_2(arr):
lala = None
for i in range(len(arr), 0, -1):
lala = i
def correct_iterate_reversed(arr):
lala = None
for obj in reversed(arr):
lala = obj
print(sys.version)
print('iterate_through_list_1', timeit.timeit('iterate_through_list_1(seq)',
setup='from __main__ import iterate_through_list_1\nseq = range(0, 10000)',
number=10000))
print('iterate_through_list_2', timeit.timeit('iterate_through_list_2(seq)',
setup='from __main__ import iterate_through_list_2\nseq = range(0, 10000)',
number=10000))
print('correct_iterate_reversed', timeit.timeit('correct_iterate_reversed(seq)',
setup='from __main__ import correct_iterate_reversed\nseq = range(0, 10000)',
number=10000))
结果:
2.7.12 (default, Jun 29 2016, 14:05:02)
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)]
iterate_through_list_1 3.87919592857
iterate_through_list_2 3.38339591026
correct_iterate_reversed 2.78083491325
3.x中的差异都是可以忽略不计的,因为在每种情况下迭代的对象都是懒惰的。
3.5.2 (default, Jul 28 2016, 21:28:00)
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)]
iterate_through_list_1 2.986786328998278
iterate_through_list_2 2.9836046030031866
correct_iterate_reversed 2.9411962590020266