在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管理内存的方式是否有用?
答案 0 :(得分:1)
您正在对内部列表(即行)进行浅拷贝,如果内部列表只是{{1}的列表,则实际上与外部列表的深层副本相同}对象。
对于整数列表的特殊情况,您已经实现了深度复制功能。
使用int
会比较慢,因为该功能将必须调查并缓存对象的所有ID,包括copy.deepcopy
对象。您的代码段没有这样做,但是在这种特殊情况下,这并不重要(请注意,小的int
对象是在解释器级别缓存的,它们本质上是单例对象,无论如何,int
对象是不可变的,因此根本不需要复制它们。
如果您想确切地了解通用深层复制所涉及的内容,这里为link to the copy
module source code。
答案 1 :(得分:0)
我认为您对浅浅和深浅的副本有误解。
浅表副本会复制集合的结构(本质上是内存位置),而深表副本会复制内存中的所有内容(与实际数据一样)。
您在这里所做的是从原始2d列表中形成每个子列表的副本的新列表-这样就形成了一个全新列表,其中与原始列表没有联系-因此,您已经完成了深层复制。
相反,如果您要执行以下操作:cur[:]
,则只复制包含与内部列表相同引用的外部列表-因此是浅拷贝。
在您的情况下,由于所有内存位置都不相同,因此更改一个元素不会影响原始元素,但是如果您只是执行cur[:]
,则内部行将引用内存中的相同位置,因此从任何一个列表中更改元素都会影响另一个列表。