According to this Official Documentation:
list[:]
creates a new list by shallow copy. I performed following experiments:
>>> 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
All here look good! new_square and square are different object (list here), but because of shallow copy, they share the same content. However, the following results make me confused:
>>> new_squares[0] = 0
>>> new_squares
[0, 4, 9, 16, 25]
>>> squares
[1, 4, 9, 16, 25]
I update new_square[0] but square is not affected. I checked their ids:
>>> id(new_squares[0])
4466081824
>>> id(squares[0])
4466081856
You can find that the id of squares[0] keeps no change but the id of new_squares[0] changes. This is quite different from the shallow copy I have understood before.
Could anyone can explain it? Thanks!
You have a list object that represents a container of other objects. When you do a shallow copy, you create a new list object (as you see) that contains references to the same objects that the original list contained.
new_squares[0] = 0
is an assignment. You're saying "set a new object at the 0th index of the list". Well, the lists are now separate objects and you're flatly replacing the object held at an index of the copy. It wouldn't matter if the object at the 0th index was mutable either, since you're just replacing the reference that the list object holds.
If the list instead contained a mutable object and you were to modify that object in place without completely changing what object is stored in that index, then you would see the change across both lists. Not because the lists are in any way linked, but because they hold reference to a mutable object that you have now changed.
This can be illustrated below, where I can separately make modifications to the shallow-copied list, and also cause a mutable object to change across both lists, even when that mutable object is now at difference indices between the two.
# 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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With