清单的浅表[:]

时间:2019-04-16 07:42:53

标签: python copy

根据此Official Documentation

list[:]

通过浅拷贝创建新列表。我进行了以下实验:

>>> squares = [1, 4, 9, 16, 25]
>>> new_squares = square[:]
>>> squares is new_squares
False
>>> squares[0] is new_squares[0]
True
>>> id(squares)
4468706952
>>> id(new_squares)
4468425032
>>> id(squares[0])
4466081856
>>> id(new_squares[0])
4466081856

这里的一切看起来不错! new_square和square是不同的对象(在此处列出),但是由于浅拷贝,它们共享相同的内容。但是,以下结果使我感到困惑:

>>> new_squares[0] = 0
>>> new_squares
[0, 4, 9, 16, 25]
>>> squares
[1, 4, 9, 16, 25]

我更新了new_square [0],但square不受影响。我检查了他们的ID:

>>> id(new_squares[0])
4466081824
>>> id(squares[0])
4466081856

您会发现squares [0]的ID不变,但new_squares [0]的ID不变。这与我之前了解的浅表副本完全不同。

任何人都可以解释吗?谢谢!

2 个答案:

答案 0 :(得分:1)

您有一个列表对象,该列表对象表示其他对象的容器。进行浅表复制时,您将创建一个新的列表对象(如您所见),其中包含对原始列表所包含的相同对象的引用。

new_squares[0] = 0是一项作业。您说的是“在列表的第0个索引处设置一个新对象”。好了,列表现在是单独的对象,您将完全替换保存在副本索引处的对象。不管第0个索引处的对象是否也是可变的,都没有关系,因为您只是替换了 list 对象持有的引用。

如果列表中包含一个可变对象,而您要就地修改该对象,而又不完全更改该索引中存储的对象,那么您将在两个列表中看到更改。不是因为列表以任何方式链接在一起,而是因为它们持有对您现在已更改的可变对象的引用。

这可以在下面进行说明,在这里我可以分别对浅表复制的列表进行修改,并且即使两个对象之间处于可变索引,也可以使一个可变对象在两个列表之间进行更改。

# MAKING A CHANGE TO THE LIST
a = [1, {'c': 'd'}, 3, 4]
b = a[:]
b.insert(0, 0)

print(a)
print(b)
print()

# MODIFYING A MUTABLE OBJECT INSIDE THE LIST
a[1]['c'] = 'something_else'

print(a)
print(b)

答案 1 :(得分:0)

列表是可变的,整数是不可变的

当您这样做:

squares = [1, 4, 9, 16, 25]
new_squares = square[:]

square和new_squares具有不同的ID

如果您这样做:

[id(squares[i]) for i in range(len(squares))]
[id(new_squares[i]) for i in range(len(new_squares))]

您将为每个整数看到相同的ID。 如果您使用其他值修改一个整数,则此整数将具有一个新的ID