如何在Python中反转一个列表但不修改原始列表

8

我正在尝试使用reverse()方法,具体如下:

>>> L=[1,2,3]
>>> R=L
>>> L.reverse()
>>> L
[3, 2, 1]
>>> R
[3, 2, 1]

为什么它也会反转 R? 如何保留原始列表并创建一个反向的列表?
谢谢!

1
http://nedbatchelder.com/text/names.html - Karl Knechtel
6个回答

7

你需要复制你的列表

L=[1,2,3]
# R=L
R = L[:]
L.reverse()

或者更直接地(使用切片符号进行反转):
R = L[::-1]

如果您只写R = L,那么R只是 L列表上的新引用。为了复制列表中的元素,请使用copy.deepcopyR = L[:] 仅产生浅层副本 (在列表中只有int时可以这样做)。

3
请注意,最简单的解决方案是将浅复制切片与反转结合起来,以获得经典的反转切片:R = L[::-1] - ShadowRanger

1
为避免翻转 R,您需要一份 L 的副本。
要制作副本,请更改:
R=L    <---- this is not copying L in to R

to

R= L[:]    <---- this will create a copy of L in to R

1
>>> L=[1,2,3]
>>> R=list(reversed(L))
>>> R
[3, 2, 1]
>>> L
[1, 2, 3]

0

这样就可以了

R = L[:]

阅读有关复制和深度复制的内容,以了解为什么会发生这种情况。简而言之,这是因为当您执行R = L时,两者都指向内存中的“相同”列表,因此反转一个将反转另一个。

或者,您可以使用deepcopy


0

操作

R=L

这意味着变量R存储了变量L所存储的内容,即R引用L引用的任何值。现在,当您反转L时,这意味着L引用的列表被反转。由于R也引用相同的地址,因此您会看到R被反转。


0

你被Python分配引用而非副本的事实所困扰。

Python使用引用来避免不必要的复制。在传递函数参数时,甚至在默认函数参数中,Python也使用引用。只有当你明确告诉它时,例如通过执行以下操作时,它才会进行复制:

L = list(R)

或者

from copy import copy
L = copy(R)

两者之间的区别在于list(R)始终返回一个列表,而copy返回与原始对象相同类型的对象。此外,copy无法使用迭代器,但list可以。

请注意,这些是“浅层”副本。如果列表包含对象,则新列表包含对相同对象的引用。对于“深层”副本,模块copy中有deepcopy函数。

from copy import deepcopy
L = deepcopy(R)

但在实践中很少需要进行显式副本。 Python 提供了例如内置的 reversed 可用于遍历列表。

for l in reversed(L):
    # do stuff

它返回一个迭代器,因此非常高效。不需要复制列表。其他需要复制的情况可以通过生成器函数等方式处理。需要复制的有效情况可能是在线程边界传递数据时。


谢谢。我尝试了一下,但是出现了以下情况:
L=[1,2,3] R=reversed(L) R <list_reverseiterator object at 0x02DB0E10>
我做错了什么?
- Hana
reversed 的结果不是为了存储在一个变量中,而是用于在 for 循环(或列表推导式)中使用。没有必要存储重复的数据... 我已经更新了我的回答。 - EvertW
@Hana 你需要 R=list(reversed(L)) - campeterson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接