它如何在Python的复制和内存系统中工作?

时间:2019-04-28 11:26:38

标签: python

它如何用于Python的内存引用?

当我在矩阵上尝试程序时,我使用了嵌套列表。然后,我发现原始数据被突变了,即使我复制了它。我尝试了几种方法。最后,我使用copy.deepcopy()解决了问题。那么,Python的复制和引用函数是什么意思。我们如何避免这种s-(问题)。

data = [
[1,0,0,1,0,0,1,1,1],
[1,0,1,0,0,0,0,1,0],
[1,1,0,0,0,0,0,1,0],
[1,0,1,0,0,0,0,1,0],
[1,0,0,1,0,0,1,1,1],
[0,0,0,0,0,0,0,0,0],
]
# data1 = data.copy() # нет
# data1 = data[:] # нет
# data1 = list(data) # нет
# data1 = list(data) # нет
# data1 = copy.copy(data) # нет
# for all of above five, data1 will change with data, even they differ from ID

对于这五个,我们将看到:

data[0][0] = 0
print(id(data))
print(id(data1))
print(data)
print(data1)
# Out:
# 4450009608
# 4450115528
# [[0, 0, 0, 1, 0, 0, 1, 1, 1], [1, 0, 1, 0, 0, 0, 0, 1, 0], [1, 1, 0, 0, 0, 0, 0, 1, 0], [1, 0, 1, 0, 0, 0, 0, 1, 0], [1, 0, 0, 1, 0, 0, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0]]
# [[0, 0, 0, 1, 0, 0, 1, 1, 1], [1, 0, 1, 0, 0, 0, 0, 1, 0], [1, 1, 0, 0, 0, 0, 0, 1, 0], [1, 0, 1, 0, 0, 0, 0, 1, 0], [1, 0, 0, 1, 0, 0, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0]]

因此,我们必须使用Deepcopy,例如一个小坑。

3 个答案:

答案 0 :(得分:1)

这在the documentation of the copy module中有详细解释:

  

浅复制和深复制之间的差异仅与   复合对象(包含其他对象的对象,例如列表或   类实例):

     

浅表副本构造一个新的复合对象,然后(到   在可能的范围内)将引用插入其中   原本的。深层副本会构造一个新的复合对象,然后,   递归地将在其中找到的对象的副本插入其中   原始的。

您在第一个示例中所做的所有尝试只会创建浅表副本。

答案 1 :(得分:0)

data1 = data.copy()和此data1 = data[:]都进行复制,但是仅一层深。在第一级以下,仅引用被复制。这就是为什么您没有在第二层看到期望的原因。

答案 2 :(得分:0)

例如,iddata的{​​{1}}会不同:

data1

但是内部列表仍将指向相同的对象并具有相同的data1 = list(data) ,这就是为什么您必须使用id将原始deepcopy的全部内容复制到新对象。