它如何用于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,例如一个小坑。
答案 0 :(得分:1)
这在the documentation of the copy module中有详细解释:
浅复制和深复制之间的差异仅与 复合对象(包含其他对象的对象,例如列表或 类实例):
浅表副本构造一个新的复合对象,然后(到 在可能的范围内)将引用插入其中 原本的。深层副本会构造一个新的复合对象,然后, 递归地将在其中找到的对象的副本插入其中 原始的。
您在第一个示例中所做的所有尝试只会创建浅表副本。
答案 1 :(得分:0)
此data1 = data.copy()
和此data1 = data[:]
都进行复制,但是仅一层深。在第一级以下,仅引用被复制。这就是为什么您没有在第二层看到期望的原因。
答案 2 :(得分:0)
例如,id
和data
的{{1}}会不同:
data1
但是内部列表仍将指向相同的对象并具有相同的data1 = list(data)
,这就是为什么您必须使用id
将原始deepcopy
的全部内容复制到新对象。