我使用的是python 3.4.1
对于单个列表a=[1,2]
,如果我复制了b = a.copy()
,当我更改b
中的项目时,它就不会更改a
中的项目。<登记/>
但是,当我定义列表列表(实际上是矩阵)a = [[1,2],[3,4]]
时,我指定b = a.copy()
。我要列出的b
实际上会影响a
我检查了他们的地址,他们是不同的
谁能告诉我为什么?
ps:我所做的是b[0][0] = x
,而且a中的项目也发生了变化。
答案 0 :(得分:11)
来自copy
模块的文档:
浅层复制和深层复制之间的区别仅与复合对象(包含其他对象的对象,如列表或类实例)相关:
- 浅复制构造一个新的复合对象,然后(尽可能)将对它的引用插入到原始对象中找到的对象。
- 深层复制构造一个新的复合对象,然后以递归方式将副本插入到原始对象中找到的对象。
当您拨打常规copy.copy()
时,您正在执行浅副本。这意味着在列表列表的情况下,您将获得外部列表的新副本,但它将包含原始内部列表作为其元素。相反,您应该使用copy.deepcopy()
,这将创建外部和内部列表的新副本。
你在第一个使用copy([1,2])
的例子中没有注意到这一点的原因是像int
这样的原语是不可变的,因此如果不创建一个原语就不可能改变它们的值新实例。如果列表的内容反而是可变对象(如列表或任何具有可变成员的用户定义对象),那么在列表的两个副本中都会看到这些对象的任何变异。
答案 1 :(得分:4)
也许是列表理解:
new_list = [x[:] for x in old_list]
...但是如果你的矩阵比一层更深,那么列表理解可能不如仅使用deepcopy
那么优雅。
编辑 - 如上所述,浅拷贝仍将包含对列表内对象的引用。例如......
>>> this = [1, 2]
>>> that = [33, 44]
>>> stuff = [this, that]
>>> other = stuff[:]
>>> other
[[1, 2], [33, 44]]
>>> other[0][0] = False
>>> stuff
[[False, 2], [33, 44]] #the same problem as before
>>> this
[False, 2] #original list also changed
>>> other = [x[:] for x in stuff]
>>> other
[[False, 2], [33, 44]]
>>> other[0][0] = True
>>> other
[[True, 2], [33, 44]]
>>> stuff
[[False, 2], [33, 44]] #copied matrix is different
>>> this
[False, 2] #original was unchanged by this assignment
答案 2 :(得分:-6)
非常简单,只需这样做:
b = a
例:
>>> a = [1, 2, 3]
>>> b = a
>>> b.append(4)
>>> b
[1, 2, 3, 4]
>>> a
[1, 2, 3, 4]