微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么切片的反向列表比反向迭代器慢

如何解决为什么切片的反向列表比反向迭代器慢

这是因为reversed返回iteratorwhile切片会返回整个列表。

>>> lis = range(10)
>>> lis[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> reversed(lis)
<listreverseiterator object at 0x909dd0c>

您必须使用list()将该迭代器转换为整个列表:

>>> lis = range(10**5)
>>> %timeit lis[::-1]
100 loops, best of 3: 2.8 ms per loop
>>> %timeit list(reversed(lis))
100 loops, best of 3: 3.13 ms per loop

reversed

>>> 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中,至少有两种方法可以反转列表,但是迭代器方法要快得多(至少在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

我怀疑速度差异至少是由于以下原因造成的:

  1. reversed 用C写的
  2. 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中实现的吗?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。