Python 阵列切片看起来像是在做深度拷贝?

Python 阵列切片看起来像是在做深度拷贝?,python,copy,deep-copy,shallow-copy,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 这让它看起来像是一个深度复制品 我有两个问题: 这里发生了什么事?这是深度复制还是浅显复制? 2这

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
这让它看起来像是一个深度复制品

我有两个问题: 这里发生了什么事?这是深度复制还是浅显复制? 2这种语法比copy.deepcopy快得多,这是怎么回事?例如,它是否与python管理内存的方式有关?

您正在制作内部列表的浅拷贝,即行,如果内部列表只是int对象的列表,则实际上与外部列表的深拷贝相同

实际上,您已经为整数列表的特殊情况实现了一个深度复制函数

使用copy.deepcopy会更慢,因为该函数必须调查和缓存对象的所有id,包括int对象。您的代码段并没有这样做,但在这个特定的例子中,这并不重要。注意,小的int对象在解释器级别缓存,它们本质上是单例的,而且无论如何,int对象是不可变的,所以它们实际上根本不必被复制


这里有一个例子,如果你不想确切地了解一般深度拷贝所涉及的内容。

我认为你对什么是浅层拷贝和深层拷贝有误解

浅拷贝复制集合的结构(本质上是内存位置),而深拷贝复制内存中实际数据中的所有内容

您在这里所做的是从原始2d列表中形成每个子列表的副本的新列表-从而产生一个与原始列表没有关联的全新列表-因此您已经完成了深度副本

相反,如果您要执行:cur[:],则只需将包含相同引用的外部列表复制到内部列表,因此是一个浅层副本


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

您认为这些切片复制的是什么?我不确定:每行的深度副本?为什么您认为它是每行的深度副本?您会从每行的浅层副本中看到不同的结果吗?cur的浅层副本将是cur2=cur[:]。您通过进入cur内部并复制每一行来执行深度复制。@user2357112是-如果是浅层复制,则foo将位于cur中。修改cur2也会修改cur。谢谢。我不确定我是否遵循了关于int对象的部分-缓存对象的id完成了什么?那么,在解释器级别缓存意味着什么?普通对象在什么级别缓存?@user2009020从-2到256的小int对象由CPython实现缓存,这就是我所说的解释器级别。阅读更多关于这方面的信息。复制模块使用Python中的dict创建自己的缓存。无论如何,您都不必复制int对象,因为它们是不可变的。但是,copy.deepcopy事先不知道它要复制的对象的任何信息,因此它会检查它已经看到的对象,以避免循环。所以我可以说copy.deepcopy速度较慢,因为它复制每个int对象,而我问题中的代码不知道?@user2009020不,它不会复制每个int对象,对于不可变的对象,原子只是返回x。但是,它检查每个对象,仍然缓存id。