我想复制一个二维列表,这样如果我修改其中一个列表,另一个列表不会被修改。
对于一维列表,我只需要这样做:
a = [1, 2]
b = a[:]
现在,如果我修改b
,a
不会被修改。
但是这对于二维列表并不起作用:
a = [[1, 2],[3, 4]]
b = a[:]
如果我修改 b
,a
也会被修改。
我该怎么解决这个问题?
若要获得一个更加通用的解决方案,不受维度数量限制,可以使用 copy.deepcopy()
:
import copy
b = copy.deepcopy(a)
from ... import ...
是正常情况,除非存在命名空间冲突:http://www.python.org/dev/peps/pep-0008/(参见“Imports”)。 - Amberb = [x[:] for x in a]
b
是新列表,a
是旧的。x
在内部使用。 - Artemispath
是一个二维数组,我想复制 path[i]
,所以我做了 curr_level = [x[:] for x in path[i]]
。 - mLstudent33为什么 b = a[:]
不适用于嵌套列表(或者说多维列表)?
a = [[1, 2],[3, 4]]
b = a[:]
答案:尽管我们使用切片操作[:]
复制列表a
,但内部子列表仍然指向列表b
的内部子列表。
注意:我们可以使用Python中的id()
检查引用(reference)。
让我们通过一个例子来理解。
>>> a = [[1,2],[3,4]]
>>> id(a)
140191407209856 # unique id of a
>>> b=a
>>> id(b)
140191407209856
>>> b=a[:] # Copying list a to b with slicing
>>> id(b)
140191407209920 # id of list b changed & is not same as id of list a
>>> id(a[0])
140191407188544
>>> id(b[0])
140191407188544
>>> id(a[0])==id(b[0]) # id of both a[0] & b[1] is same.
True
a [0]
的引用与b [0]
相同。copy.deepcopy(a)
[item [:] for item in a]
[item.copy() for item in a]
[list(item) for item in a]
[copy.copy(item) for item in a]
[]; b.extens[a]
下面是所有可用复制方法的时间复杂度比较(source)
10.59秒(每次105.9微秒) - copy.deepcopy(old_list)
的深拷贝
10.16秒(每次101.6微秒) - 使用纯Python Copy()
方法复制类并进行深拷贝
1.488秒(每次14.88微秒) - 使用纯Python Copy()
方法不复制类(只复制字典/列表/元组)
0.325秒(每次3.25微秒) - for item in old_list: new_list.append(item)
0.217秒(每次2.17微秒) - [i for i in old_list]
(一个列表推导式)
0.186秒(每次1.86微秒) - copy.copy(old_list)
的浅拷贝
0.075秒(每次0.75微秒) - list(old_list)
0.053秒(每次0.53微秒) - new_list = []; new_list.extend(old_list)
0.039秒(每次0.39微秒) - old_list[:]
(列表切片)
numpy
。 - Mike Grahamb = a[:]
时,你创建了一个新的列表b
,所以例如a.append([5, 6])
将不会修改b
,因为它只是改变了a
。然而,行a[1][0] = 5
将 改变b
,因为它改变了b
引用的列表。 - Artemisa = [[1, 2], [3, 4]]
定义变量a
,然后创建a
的一个副本:b = a.copy()
。这是一个不同的列表,但它包含相同的“子列表”。这意味着更改b
,例如b.append([5, 6])
不会更改a
,但是更改b
中的一个列表,例如b[0].append(3)
也会更改a
中的第一个列表。 - Artemis