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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3705670/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 12:21:28  来源:igfitidea点击:

Best way to create a "reversed" list in Python?

pythonreversehtml-lists

提问by davidchambers

In Python, what is the best way to create a new list whose items are the same as those of some other list, but in reverse order? (I don't want to modify the existing list in place.)

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

Here is one solution that has occurred to me:

这是我想到的一种解决方案:

new_list = list(reversed(old_list))

It's also possible to duplicate old_listthen reverse the duplicate in place:

也可以复制old_list然后原地反转副本:

new_list = list(old_list) # or `new_list = old_list[:]`
new_list.reverse()

Is there a better option that I've overlooked? If not, is there a compelling reason (such as efficiency) to use one of the above approaches over the other?

有没有我忽略的更好的选择?如果不是,是否有令人信服的理由(例如效率)使用上述方法之一而不是另一种方法?

采纳答案by Alex Martelli

newlist = oldlist[::-1]

The [::-1]slicing (which my wife Anna likes to call "the Martian smiley";-) means: slice the whole sequence, with a step of -1, i.e., in reverse. It works for all sequences.

[::-1]切片(其中我的妻子安娜喜欢称之为“火星笑脸” ;-)方式:切片的整个序列,为-1的步骤,即逆转。它适用于所有序列。

Note that this (andthe alternatives you mentioned) is equivalent to a "shallow copy", i.e.: if the items are mutable and you call mutators on them, the mutations in the items held in the original list are also in the items in the reversed list, and vice versa. If you need to avoid that, a copy.deepcopy(while always a potentially costly operation), followed in this case by a .reverse, is the only good option.

请注意,这(以及您提到的替代方案)等效于“浅拷贝”,即:如果项目是可变的并且您对它们调用了修改器,则原始列表中保存的项目中的突变也在反转列表,反之亦然。如果您需要避免这种情况, a copy.deepcopy(虽然总是一个潜在的成本高昂的操作),在这种情况下是 a .reverse,是唯一的好选择。

回答by Sam Dolan

Now let's timeit. Hint:Alex's [::-1]is fastest :)

现在让我们timeit提示: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

Update:Added list comp method suggested by inspectorG4dget. I'll let the results speak for themselves.

更新:添加了inspectorG4dget 建议的list comp 方法。我会让结果不言自明。

回答by mekarpeles

Adjustments

调整

It's worth providing a baseline benchmark/adjustment for the timeit calculations by sdolan which show the performance of 'reversed' without the often unnecessary list()conversion. This list()operation adds an additional 26 usecs to the runtime and is only needed in the event an iterator is unacceptable.

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

Results:

结果:

reversed(lst) -- 11.2 usecs

list(reversed(lst)) -- 37.1 usecs

lst[::-1] -- 23.6 usecs

Calculations:

计算:

# 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

Conclusions:

结论:

The conclusion of these tests is reversed()is faster than the slice [::-1]by 12.4 usecs

这些测试的结论reversed()比切片快[::-1]12.4 微秒