数组切片似乎在制作深层副本?

时间:2018-08-05 18:46:03

标签: python copy deep-copy shallow-copy

在python中切片应该是浅拷贝。但是,当我运行以下命令时:

cur = [[0] * (2) for _ in xrange(2)]
cur2 = [row[:] for row in cur]
cur2[0][0] = "foo"
print(cur)
print(cur2)

我得到:

[[0, 0], [0, 0]] # cur
[['foo', 0], [0, 0]] # cur2

这看起来像是一个深层副本。

我有两个问题: 1)这是怎么回事?这是深拷贝还是浅拷贝? 2)这种语法使它比copy.deepcopy快得多吗?例如,python管理内存的方式是否有用?

2 个答案:

答案 0 :(得分:1)

您正在对内部列表(即行)进行浅拷贝,如果内部列表只是{{1}的列表,则实际上与外部列表的深层副本相同}对象。

对于整数列表的特殊情况,您已经实现了深度复制功能。

使用int会比较慢,因为该功能将必须调查并缓存对象的所有ID,包括copy.deepcopy对象。您的代码段没有这样做,但是在这种特殊情况下,这并不重要(请注意,小的int对象是在解释器级别缓存的,它们本质上是单例对象,无论如何,int对象是不可变的,因此根本不需要复制它们。

如果您想确切地了解通用深层复制所涉及的内容,这里为link to the copy module source code

答案 1 :(得分:0)

我认为您对浅浅和深浅的副本有误解。

浅表副本会复制集合的结构(本质上是内存位置),而深表副本会复制内存中的所有内容(与实际数据一样)。

您在这里所做的是从原始2d列表中形成每个子列表的副本的新列表-这样就形成了一个全新列表,其中与原始列表没有联系-因此,您已经完成了深层复制

相反,如果您要执行以下操作:cur[:],则只复制包含与内部列表相同引用的外部列表-因此是浅拷贝

>

在您的情况下,由于所有内存位置都不相同,因此更改一个元素不会影响原始元素,但是如果您只是执行cur[:],则内部行将引用内存中的相同位置,因此从任何一个列表中更改元素都会影响另一个列表。