更改浅拷贝中的列表元素

时间:2018-01-10 00:54:32

标签: python list shallow-copy

我有一个关于列表浅拷贝的问题。

在这两个示例中,我修改了列表中的一个元素,但在示例1中,列表b已更改,而在示例2中,列表d未更改。我很困惑因为在这两个例子中,我修改了列表的一个元素。

有什么区别?

示例1:

a=[1,2,[3,5],4]
b=list(a)
a[1]=0
print(a)   # [1, 0, [3, 5], 4]
print(b)   # [1, 2, [3, 5], 4]

示例2:

c=[1,2,[3,5],4]
d=list(c)
c[2][0]=0
print(c)   # [1, 2, [0, 5], 4]
print(d)   # [1, 2, [0, 5], 4]

3 个答案:

答案 0 :(得分:3)

浅拷贝意味着您获得一个新列表但元素是相同的。因此,两个列表都具有相同的第一个元素,第二个元素等。

如果添加,删除或替换浅层复制列表中的值,则更改未反映在原始列表中(反之亦然),因为浅层副本创建了新列表。但是,如果您更改中的某个元素,则两个列表中都会显示更改,因为两个列表都引用相同的项目。因此,内部列表实际上在新列表和旧列表之间共享,如果您更改它,则两者都可以看到该更改。

请注意,您实际上没有更改任何一个示例中的元素,您在第一个示例中替换列表中的元素,而在第二个示例中,您替换列表元素的元素。

我目前正在使用graphviz,所以让我添加一些图片来说明这一点:

浅层拷贝意味着您获得了一个新列表,但列表中存储的对象是相同的:

enter image description here

如果替换其中任何一个元素,相应的元素将仅引用一个新项目(您的第一个示例)。看一个列表如何引用这两个列表,另一个列表引用零:

enter image description here

虽然对引用项目的更改将更改该项目,并且引用该项目的每个对象都将看到更改:

enter image description here

答案 1 :(得分:1)

after changing values [before changing valuesafter changing values 1。 =复制对象的引用,因此任一列表中的任何更改都会反映在另一个

  1. phpinfo->做相同的工作。 也就是说,它仅复制单个对象的引用,例如b [0] = a [0]和b 2 = a 2,依此类推。使用int,string等,就好像x = 10和y = x并且更改'x'或'y'的值不会影响其他值一样。当您进行浅表复制时,a和b的其余元素会发生这种情况。

因此,如在您的问题中使用浅拷贝进行b=list(a) or b=a.copy()时的行为如上所述,因此更改不会同时反映在两个列表中。但是嵌套的列出列表就像b=list(a) and a[1]=0a=[1,2,3]一样作为列表分配,使a 2 = 3也会将b 2更改为3,即a或b效果的变化两者(与上述情况1相同)。因此,这就是为什么在列表中包含列表的情况下,任何更改都会反映在两个列表中的原因。就像您在示例中进行b=a一样(此处复制d=list(c)时类似于列表分配,即复制了引用,并且在列表分配的情况下两者都反映出更改,因此对d {2的更改或c 2都反映在两个列表中),因此d[2]=c[2]也会将d [2] [0]更改为零。

http://www.pythontutor.com/visualize.html#mode=edit处尝试代码 更好地了解

c[2][0] = 0

答案 2 :(得分:0)

在这两个示例中,您将创建列表的浅表副本。浅拷贝基本上将别名复制到第一个列表中的所有元素到第二个列表。

因此您已将引用复制到[int, int, list, int]int元素是不可变的,但list元素可变的。所以第三个元素都指向Python内存中的同一个对象。修改该对象会修改对它的所有引用。