我正在尝试使用reverse()方法,具体如下:
>>> L=[1,2,3]
>>> R=L
>>> L.reverse()
>>> L
[3, 2, 1]
>>> R
[3, 2, 1]
为什么它也会反转 R? 如何保留原始列表并创建一个反向的列表?
谢谢!
我正在尝试使用reverse()方法,具体如下:
>>> L=[1,2,3]
>>> R=L
>>> L.reverse()
>>> L
[3, 2, 1]
>>> R
[3, 2, 1]
你需要复制你的列表
L=[1,2,3]
# R=L
R = L[:]
L.reverse()
R = L[::-1]
R = L
,那么R
只是 L
列表上的新引用。为了复制列表中的元素,请使用copy.deepcopy
;R = L[:]
仅产生浅层副本 (在列表中只有int时可以这样做)。R = L[::-1]
。 - ShadowRangerR
,您需要一份 L
的副本。R=L <---- this is not copying L in to R
to
R= L[:] <---- this will create a copy of L in to R
>>> L=[1,2,3]
>>> R=list(reversed(L))
>>> R
[3, 2, 1]
>>> L
[1, 2, 3]
这样就可以了
R = L[:]
阅读有关复制和深度复制的内容,以了解为什么会发生这种情况。简而言之,这是因为当您执行R = L
时,两者都指向内存中的“相同”列表,因此反转一个将反转另一个。
或者,您可以使用deepcopy。
操作
R=L
这意味着变量R存储了变量L所存储的内容,即R引用L引用的任何值。现在,当您反转L时,这意味着L引用的列表被反转。由于R也引用相同的地址,因此您会看到R被反转。
你被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
它返回一个迭代器,因此非常高效。不需要复制列表。其他需要复制的情况可以通过生成器函数等方式处理。需要复制的有效情况可能是在线程边界传递数据时。
- HanaL=[1,2,3] R=reversed(L) R <list_reverseiterator object at 0x02DB0E10>
我做错了什么?
reversed
的结果不是为了存储在一个变量中,而是用于在 for 循环(或列表推导式)中使用。没有必要存储重复的数据... 我已经更新了我的回答。 - EvertWR=list(reversed(L))
。 - campeterson