分配后列表意外更改.为什么会这样,我该如何预防? [英] List changes unexpectedly after assignment. Why is this and how can I prevent it?
问题描述
使用 new_list = my_list
时,对 new_list
的任何修改每次都会更改 my_list
.为什么会这样,以及如何克隆或复制列表以阻止它?
While using new_list = my_list
, any modifications to new_list
changes my_list
every time. Why is this, and how can I clone or copy the list to prevent it?
推荐答案
使用 new_list = my_list
,您实际上没有两个列表.分配只是将引用复制到列表,而不是实际列表,因此 new_list
和 my_list
都在分配后引用同一列表.
With new_list = my_list
, you don't actually have two lists. The assignment just copies the reference to the list, not the actual list, so both new_list
and my_list
refer to the same list after the assignment.
要实际复制列表,您有多种可能:
To actually copy the list, you have various possibilities:
-
您可以使用内置的
列表.copy()
方法(自Python 3.3起可用):
You can use the builtin
list.copy()
method (available since Python 3.3):
new_list = old_list.copy()
您可以对其进行切片:
You can slice it:
new_list = old_list[:]
Alex Martelli's opinion (at least back in 2007) about this is, that it is a weird syntax and it does not make sense to use it ever. ;) (In his opinion, the next one is more readable).
您可以使用内置的 list()
函数:
You can use the built in list()
function:
new_list = list(old_list)
您可以使用通用的 copy.copy()
:
import copy
new_list = copy.copy(old_list)
这比 list()
慢一点,因为它必须先找出 old_list
的数据类型.
This is a little slower than list()
because it has to find out the datatype of old_list
first.
如果列表包含对象,并且您也要复制它们,请使用通用 copy.deepcopy()
:
If the list contains objects and you want to copy them as well, use generic copy.deepcopy()
:
import copy
new_list = copy.deepcopy(old_list)
显然是最慢且最需要内存的方法,但有时是不可避免的.
Obviously the slowest and most memory-needing method, but sometimes unavoidable.
示例:
import copy
class Foo(object):
def __init__(self, val):
self.val = val
def __repr__(self):
return 'Foo({!r})'.format(self.val)
foo = Foo(1)
a = ['foo', foo]
b = a.copy()
c = a[:]
d = list(a)
e = copy.copy(a)
f = copy.deepcopy(a)
# edit orignal list and instance
a.append('baz')
foo.val = 5
print('original: %r\nlist.copy(): %r\nslice: %r\nlist(): %r\ncopy: %r\ndeepcopy: %r'
% (a, b, c, d, e, f))
结果:
original: ['foo', Foo(5), 'baz']
list.copy(): ['foo', Foo(5)]
slice: ['foo', Foo(5)]
list(): ['foo', Foo(5)]
copy: ['foo', Foo(5)]
deepcopy: ['foo', Foo(1)]
这篇关于分配后列表意外更改.为什么会这样,我该如何预防?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!