Python 为什么使用切片反转列表比反转迭代器慢
在Python中,至少有两种方法可以反转列表,但迭代器方法要快得多(至少在Python 2.7.x中是如此)。我想了解是什么导致了这种速度差Python 为什么使用切片反转列表比反转迭代器慢,python,Python,在Python中,至少有两种方法可以反转列表,但迭代器方法要快得多(至少在Python 2.7.x中是如此)。我想了解是什么导致了这种速度差 >>> x = range(1000) >>> %timeit x[::-1] 100000 loops, best of 3: 2.99 us per loop >>> %timeit reversed(x) 10000000 loops, best of 3: 169 ns per loop 我怀
>>> x = range(1000)
>>> %timeit x[::-1]
100000 loops, best of 3: 2.99 us per loop
>>> %timeit reversed(x)
10000000 loops, best of 3: 169 ns per loop
我怀疑速度差异至少是由以下原因造成的:
reversed
是用C编写的reversed
是一个迭代器,因此内存开销更小dis
模块来更好地了解这些操作,但没有太大帮助。我必须把这些操作放到一个函数中去分解它们
>> def reverselist(_list):
... return _list[::-1]
...
>>> dis.dis(reverselist)
2 0 LOAD_FAST 0 (_list)
3 LOAD_CONST 0 (None)
6 LOAD_CONST 0 (None)
9 LOAD_CONST 1 (-1)
12 BUILD_SLICE 3
15 BINARY_SUBSCR
16 RETURN_VALUE
>>> def reversed_iter(_list):
... return reversed(_list)
...
>>> dis.dis(reversed_iter)
2 0 LOAD_GLOBAL 0 (reversed)
3 LOAD_FAST 0 (_list)
6 CALL_FUNCTION 1
9 RETURN_VALUE
在切片操作中到底发生了什么,内存开销是否很大?也许切片是在纯Python中实现的?这是因为
reversed
返回一个列表,而切片返回一个完整的列表
>>> lis = range(10)
>>> lis[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> reversed(lis)
<listreverseiterator object at 0x909dd0c>
帮助打开反向
:
>>> reversed?
Type: type
String Form:<type 'reversed'>
Namespace: Python builtin
Docstring:
reversed(sequence) -> reverse iterator over values of the sequence
Return a reverse iterator
>>反向?
类型:类型
字符串形式:
名称空间:Python内置
文档字符串:
反向(序列)->序列值上的反向迭代器
返回一个反向迭代器
reversed()
返回迭代器。它实际上不会反转任何东西,直到你在它上面循环。从:
返回一个反向
您需要比较将reversed()
的结果再次转换为列表所需的时间:
%timeit list(reversed(x))
只创建迭代器(它只是对原始列表的引用和初始化为列表长度的项指针)根本不需要任何时间
必须将reversed()
返回到列表中会使速度慢很多:
reversed()
实际上并不反转任何内容,它只返回一个对象,该对象可用于按相反顺序遍历容器的元素。这就是为什么它比实际反转元素更快的原因
请注意,还有与切片操作符相同的reverse()
reverse()
操作到位。切片操作符返回一个列表对象。很抱歉,我没有提到主题,但是在哪个python版本中,?
可以提供帮助?天哪,这似乎很明显,显然对我来说还为时过早。谢谢你的解释@septi?
在Ipython shell中,而不是Python的特定版本。@septi它是Ipython shell。不确定我怎么会错过这个。谢谢你的解释。顺便说一句,我不必为了使用dis
模块而将这些操作放到方法中。有一个很好的lambda
,首先编译代码字符串(必需),然后将其传递到dis.dis
list.reverse()
操作到位,而不是反向
。
%timeit list(reversed(x))
>>> import timeit
>>> x = range(1000)
>>> timeit.timeit('x[::-1]', 'from __main__ import x')
4.623600006103516
>>> timeit.timeit('list(reversed(x))', 'from __main__ import x')
16.647125005722046