尽可能快地反向迭代Python列表

9

我正在使用Python 3.2.3。在列表中以相反的方式迭代,最快的方法是什么? [::-1]、reversed、list.reverse()或其他方法?我正在处理大约5e6个元素的列表,所以我真的需要避免复制列表。


3
你应该亲自测试一下。我建议你查看timeit模块 - Joel Cornett
2个回答

17
>>> from timeit import Timer
>>> t = Timer('[x for x in l[::-1]]', 'l = list(range(100000))')
>>> t.timeit(number=1000)
5.549649953842163
>>> t = Timer('l.reverse(); [x for x in l]', 'l = list(range(100000))')
>>> t.timeit(number=1000)
4.548457145690918
>>> t = Timer('[x for x in reversed(l)]', 'l = list(range(100000))')
>>> t.timeit(number=1000)
4.428632974624634

结论:在一个有100000个项目的列表上,reversed()比l.reverse()稍微快一点。当然,如果你不实际遍历整个列表,这更加正确,如果你使用列表超过一次,它就不再正确了。
自2.4版本引入reversed()后,l[::-1]已经过时了。

我发现l.reversed()与通过迭代原始列表排序几乎相当:(t = Timer('[x for x in l]', 'l = list(range(100000))')),这是在Python 3.8中的情况。9年内会发生很多事情,我想。 - Lorem Ipsum

15

reversed 应该是最好的选择,因为它返回一个迭代器,所以不会复制列表,只会一次生成一个元素。(list.reverse() 同样不会复制列表,但它会改变列表,所以在操作后列表会倒序排列,而 reversed 不会修改原始列表。)


2
请注意,迭代器并不一定防止复制,只是在这种情况下恰好起作用。 - Ignacio Vazquez-Abrams
1
没错,但通常情况下,提供迭代器的内置Python函数不会一次性构建整个列表;这就是它们存在的全部意义。 - BrenBarn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接