何时使用反向内置而不是列表切片

时间:2014-10-19 14:51:09

标签: python list python-3.x reverse

在python中,有许多方法可以反转序列:

l = [1,2,3]
reversed(l) #returns a reverse iterator
l[::-1] #returns a reverse sequence

虽然有一个专门用于反转序列的内置函数,但使用列表切片更简洁。此外,列表切片返回一个完整的Sequence,它支持__getitem____len__,而reversed只是一个迭代器。最后,reversed需要Sequence,这意味着列表切片几乎总是有效。

使用reversed内置列表切片有什么好处?

3 个答案:

答案 0 :(得分:4)

list[::-1]返回列表的新反转副本。它将根据列表的大小消耗更多内存:列表对象的大小+ sizeof(指针)* len(列表)

如果您不需要同时使用整个列表项,则在内存方面使用reversed更为可取。 (例如,迭代列表颠倒顺序,逐个处理项目不一次需要所有项目。)

答案 1 :(得分:3)

说“reversed需要序列”是不正确的。在Python 2.6+中reversed适用于定义__reversed__方法的任何对象。因此,它可以处理不支持整数索引的对象,而切片则不能。

因此,在仅反转序列的一段时,使用切片,一次需要多个元素,或者可能需要控制步长。如果您只需要遍历每个元素(根据@fattru的答案的内存考虑),或者如果您有一个具有自定义反转行为的对象,请使用reversed

答案 2 :(得分:-1)

哦,darn,一位评论者指出rev_func没有返回列表,它返回了列表迭代器。糟糕

当我更正它时,结果基本相同。

  

使用[:: - 1]:1.6161760782445813   使用reversed():1.7324838771408098

import timeit
import random

def rev_slice(big_list):
    return big_list[::-1]


def rev_func(big_list):

    #return reversed(big_list)
    return list(reversed(big_list))


big_list = [random.random() for i in range(10000000)]

slice_t = timeit.Timer("foo = rev_slice(big_list)", "from __main__ import big_list, rev_slice")
slice_time = slice_t.timeit(10)
print ("Using [::-1]: {0}".format(slice_time))

func_t = timeit.Timer("foo = rev_func(big_list)", "from __main__ import big_list, rev_func")
func_time = func_t.timeit(10)
print ("Using reversed(): {0}".format(func_time))