在Python中创建“反向”列表的最佳方法是什么?

在Python中创建“反向”列表的最佳方法是什么?,python,reverse,html-lists,Python,Reverse,Html Lists,在Python中,创建一个新列表的最佳方法是什么,该列表的项目与其他列表的项目相同,但顺序相反?我不想修改现有的列表 我想到了一个解决方案: new_list = list(reversed(old_list)) 也可以复制旧的_列表,然后在适当的位置反转副本: new_list = list(old_list) # or `new_list = old_list[:]` new_list.reverse() 有没有我忽略的更好的选择?如果没有,是否有令人信服的理由(如效率)使用上述方法中的

在Python中,创建一个新列表的最佳方法是什么,该列表的项目与其他列表的项目相同,但顺序相反?我不想修改现有的列表

我想到了一个解决方案:

new_list = list(reversed(old_list))
也可以复制旧的_列表,然后在适当的位置反转副本:

new_list = list(old_list) # or `new_list = old_list[:]`
new_list.reverse()
有没有我忽略的更好的选择?如果没有,是否有令人信服的理由(如效率)使用上述方法中的一种而不是另一种

newlist = oldlist[::-1]
我妻子安娜喜欢称之为火星微笑的切片;-意思是:以-1的步长对整个序列进行切片,即反向切片。它适用于所有序列

请注意,这和您提到的备选方案相当于浅表副本,即:如果项目是可变的,并且您对其调用了突变子,则原始列表中的项目中的突变也在反向列表中的项目中,反之亦然。如果您需要避免这种情况,那么copy.deepcopy是唯一好的选择,而copy.deepcopy始终是一个潜在的昂贵操作,在本例中,后面跟着.reverse。提示:Alex的[:-1]是最快的:

$ p -m timeit "ol = [1, 2, 3]; nl = list(reversed(ol))"
100000 loops, best of 3: 2.34 usec per loop

$ p -m timeit "ol = [1, 2, 3]; nl = list(ol); nl.reverse();"
1000000 loops, best of 3: 0.686 usec per loop

$ p -m timeit "ol = [1, 2, 3]; nl = ol[::-1];"
1000000 loops, best of 3: 0.569 usec per loop

$ p -m timeit "ol = [1, 2, 3]; nl = [i for i in reversed(ol)];"
1000000 loops, best of 3: 1.48 usec per loop


$ p -m timeit "ol = [1, 2, 3]*1000; nl = list(reversed(ol))"
10000 loops, best of 3: 44.7 usec per loop

$ p -m timeit "ol = [1, 2, 3]*1000; nl = list(ol); nl.reverse();"
10000 loops, best of 3: 27.2 usec per loop

$ p -m timeit "ol = [1, 2, 3]*1000; nl = ol[::-1];"
10000 loops, best of 3: 24.3 usec per loop

$ p -m timeit "ol = [1, 2, 3]*1000; nl = [i for i in reversed(ol)];"
10000 loops, best of 3: 155 usec per loop
更新:添加了inspectorG4dget建议的列表补偿方法。我会让结果说明一切。

值得为sdolan的timeit计算提供一个基准/调整,它显示了“反向”的性能,而不需要经常不必要的列表转换。此列表操作向运行时添加额外的26个usecs,并且仅在迭代器不可接受的情况下才需要

结果:

计算:

结论:


这些测试的结论是相反的,比切片[:-1]快12.4倍!那很优雅。直到几天前,我才意识到切片时可以包含一个步骤;现在我想知道没有它我怎么过得去!谢谢你,亚历克斯也谢谢你提到这会产生一个肤浅的副本。这就是我所需要的,所以我准备在我的代码中添加一个火星人的笑脸。这看起来真的比最初的建议listreversedoldlist更神奇,可读性也更低。除了一个小的微优化,还有什么理由更喜欢[:-1]而不是反向的吗?@BrianCampbell:这有什么神奇之处?如果您完全理解切片,那么它完全有意义。如果您不了解切片…那么,您真的应该在Python职业生涯的早期就学习它。当然,当您不需要列表时,reversed有一个巨大的优势,因为它不会浪费内存或提前构建它。但是当您确实需要列表时,使用[:-1]而不是listreversed类似于使用[listcomp]而不是listgenexpr。@在我使用的代码中,我很少看到第三个slice参数,如果我看到它的用法,我必须查找它的含义。一旦我这样做了,当步骤为负时,默认的开始值和结束值是否交换仍然不明显。快速看一眼,如果不查找第三个参数的含义,我可能会猜[::-1]意味着删除列表的最后一个元素,而不是将其反转。reversedlist确切地说明了它在做什么;它阐明了它的意图,从显式优于隐式的意义上讲,可读性很重要,稀疏优于稠密。reversed返回一个迭代器对象,该对象被延迟计算,因此我认为它与切片表示法[:-1]一般来说是不公平的。即使在迭代器可以直接使用的情况下,例如.joinreversed['1'、'2'、'3'],切片方法的速度仍然大于30%。难怪前两次测试的结果相同:它们是相同的!我的结果与此更为相似。ol[::-1]的时间大约是listreversedol的两倍。ol[::-1]方法需要更少的字符来编写。但是,listreversedol对于python初学者来说可能更具可读性,并且在我的机器上速度更快。请注意-这对于创建反向副本列表是准确的,但是对于迭代来说,反向仍然更有效[:-1]
reversed(lst) -- 11.2 usecs

list(reversed(lst)) -- 37.1 usecs

lst[::-1] -- 23.6 usecs
# I ran this set of 100000 and came up with 11.2, twice:
python -m timeit "ol = [1, 2, 3]*1000; nl = reversed(ol)"
100000 loops, best of 3: 11.2 usec per loop

# This shows the overhead of list()
python -m timeit "ol = [1, 2, 3]*1000; nl = list(reversed(ol))"
10000 loops, best of 3: 37.1 usec per loop

# This is the result for reverse via -1 step slices
python -m timeit "ol = [1, 2, 3]*1000;nl = ol[::-1]"
10000 loops, best of 3: 23.6 usec per loop