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 callslist.__getitem__(slice(None, None))whereNone, Noneare the start and end of the slice.Calling
__getitem__on a list with a slice returns a new list object (shallow copy) made up of that slice. That meansa[:].anything()will operate on a temporary new list that was created.A slice on left side of the equals (
a[:] = value), callslist.__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.