在python中,有许多方法可以反转序列:
l = [1,2,3]
reversed(l) #returns a reverse iterator
l[::-1] #returns a reverse sequence
虽然有一个专门用于反转序列的内置函数,但使用列表切片更简洁。此外,列表切片返回一个完整的Sequence
,它支持__getitem__
和__len__
,而reversed
只是一个迭代器。最后,reversed
需要Sequence
,这意味着列表切片几乎总是有效。
使用reversed
内置列表切片有什么好处?
答案 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))