[英]How to reverse a list without modifying the original list in Python
I'm trying to use the reverse() method in the following way:我正在尝试通过以下方式使用 reverse() 方法:
>>> L=[1,2,3]
>>> R=L
>>> L.reverse()
>>> L
[3, 2, 1]
>>> R
[3, 2, 1]
Why does it reverse R as well?为什么它也会反转 R? How do I keep the original list and create a reversed on?如何保留原始列表并创建反向列表?
Thanks!谢谢!
you need to make a copy of your list你需要复制一份你的清单
L=[1,2,3]
# R=L
R = L[:]
L.reverse()
or more directly (reversing using slice notation):或更直接(使用切片符号反转):
R = L[::-1]
if you just write R = L
then R
is just a new reference on the same list L
.如果你只是写R = L
那么R
只是同一个列表L
上的一个新引用。
if you also need to copy the elements in your list, use copy.deepcopy
;如果您还需要复制列表中的元素,请使用copy.deepcopy
; R = L[:]
only produces a shallow copy (which is fine in your case where there are only int
s in the list). R = L[:]
只产生一个浅拷贝(这在你的情况下很好,列表中只有int
s)。
To avoid reversing R
, you need a copy of L
为避免反转R
,您需要一份L
的副本
To make a copy, change要复制,请更改
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]
This will do这会做
R = L[:]
Read about copying and deep copying to understand why this is happening.阅读有关复制和深度复制的内容以了解发生这种情况的原因。 In short, it is because when you do R = L
, both point to the "same" list in memory so reversing one will reverse the other.简而言之,这是因为当您执行R = L
,两者都指向内存中的“相同”列表,因此反转一个将反转另一个。
The operation操作
R=L
means that the variable R stores whatever L is storing ie R references to whatever value L is refering.意味着变量 R 存储 L 正在存储的任何内容,即 R 对 L 所引用的任何值的引用。 Now, when you reverse L, it means the list L is refering to is reversed.As R is also refereing same address, you are seeing R as reversed.现在,当您反转 L 时,这意味着 L 所引用的列表已反转。由于 R 也引用了相同的地址,因此您将看到 R 已反转。
You have been bitten by the fact that Python assigns references, not copies.您已经被 Python 分配引用而不是副本这一事实所困扰。
Python uses reference exclusively in order to prevent unneeded copies. Python 仅使用引用来防止不需要的副本。 It uses references also when passing function arguments, and even with default function arguments.它在传递函数参数时也使用引用,甚至使用默认函数参数。 It only makes a copy when you explicitly tell it to, eg by doing它仅在您明确告诉它时才会复制,例如通过执行
L = list(R)
or或者
from copy import copy
L = copy(R)
The difference between the two is that list(R)
always returns a list, where copy
returns an object of the same type as the original.两者的区别在于list(R)
总是返回一个列表,其中copy
返回一个与原始类型相同的对象。 Also, copy
does not work with iterators, but list
does.此外, copy
不适用于迭代器,但list
可以。
Note that these are 'shallow' copies.请注意,这些是“浅”副本。 If the list contains objects, the new list contains references to the same objects.如果列表包含对象,则新列表包含对相同对象的引用。 For 'deep' copies, it has the function deepcopy
in the module copy
.对于“深度”副本,它在模块copy
具有deepcopy
功能。
from copy import deepcopy
L = deepcopy(R)
But in practise there is rarely a need to make explicit copies.但在实践中很少需要制作显式副本。 Python provides eg the reversed
built-in that can be used to iterate through the list. Python 提供了例如可用于遍历列表的reversed
内置函数。
for l in reversed(L):
# do stuff
It returns an iterator, so it is efficient.它返回一个迭代器,所以它是高效的。 No need to duplicate the list.无需复制列表。 Other cases where a copy might be needed can be handled by eg generator functions.其他可能需要副本的情况可以由例如生成器函数处理。 A valid case for a copy might be when pasing data past thread boundaries.复制的有效情况可能是将数据传递到线程边界之外。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.