I tried these codes on a list slice
a[:] when I was learning list methods:
a = list('zyx') a[:].pop() print(a) a = list('zyx') a[:].append('o') print(a) a = list('zyx') a[:].clear() print(a) a = list('zyx') a[:] =  print(a)
and the results I got are:
['z', 'y', 'x'] ['z', 'y', 'x'] ['z', 'y', 'x'] 
What makes me confused is both the list methods and the reassignment changed the list slice, but why did the reassignment affect the original list while the list methods did not?
I know it might be about shallow copy, but I can not tell exactly why.
Understanding the methods underneath may be the key to success:
A slice such as
a[:] used in an expression calls
list.__getitem__(slice(None, None)) where
None, None are the start and end of the slice.
__getitem__ on a list with a slice returns a new list object (shallow copy) made up of that slice. That means
a[:].anything() will operate on a temporary new list that was created.
A slice on left side of the equals (
a[:] = value), calls
list.__setitem__(slice(None, None), value). In other words, it modifies the existing list – which is what you’d generally expect.
As @jasonharper noted, modifying a new temporary slice without another reference would be confusing and not very useful; yet another reason for the asymmetry.