就在我认为我已经理解了Python列表如何工作的时候......
>>> a = [1,2,3]
>>> b = a[:]
>>> b
[1,2,3]
>>> b[1]=100
>>> b
[1,100,3]
>>> a
[1,2,3]
到目前为止,这么好。我正在使用a的内容初始化b,以便b指向不同的对象。因此,b的变化不会影响。
现在看看另一个例子:
>>> a = [[1,2,3],[4,5,6],[7,8,9]]
>>> b = a[:][:]
>>> b
[[1,2,3],[4,5,6],[7,8,9]]
>>> b[1][1] = 100
>>> b
[[1,2,3],[4,100,6],[7,8,9]]
>>> a
[[1,2,3],[4,100,6],[7,8,9]]
为什么b的变化会影响这个时间?与前面的例子有什么不同?
答案 0 :(得分:11)
切片操作x[:]
生成浅拷贝。这意味着,外部列表不同,但包含完全相同的元素。假设a = [[1]]
:
b = a[:] # is the same as:
b = [x for x in a]
>>> a[0] is b[0]
True
双切片([:][:]
)只是做了 - 再次:
b = a[:][:] # is the same as:
b = [y for y in [x for x in a]]
>>> a[0] is b[0]
True
浅拷贝的浅拷贝是浅拷贝。
所以b
仍然是a
的浅表副本 - 这些列表是不同的对象,但它们包含相同的元素。然后你改变了b
中的内部列表,但它与a
中的列表相同。
可以使用b=[x[:] for x in a]
完成2级浅拷贝。对于n级复制,它的扩展方式相同。
顺便说一句,术语“浅拷贝”对于任何类或容器具有相同的含义。
如果您想要真正的深层复制,则应考虑使用deep copy。
答案 1 :(得分:4)
silcing [:]制作浅色副本。但是内部对象仍然没有被复制,因此如果它们是可变的,你将修改它们,它们将被修改;)并在两个列表中你将看到这个
使用列表理解
b = [i[:] for i in a]
或copy.deepcopy()
import copy
b = copy.deepcopy(a)
答案 2 :(得分:1)
试试这个:
In [38]: import copy
In [39]: a = [[1,2,3],[4,5,6],[7,8,9]]
In [40]: b=copy.deepcopy(a)
In [41]: b[1][1] = 100
In [42]: a
Out[42]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
In [43]: b
Out[43]: [[1, 2, 3], [4, 100, 6], [7, 8, 9]]