What is the difference between slice assignment that slices the whole list and direct assignment?
list, python, slice, variable-assignment
Solution
a_list = ['foo', 'bar']
Creates a new `list` in memory and points the name `a_list` at it. It is irrelevant what `a_list` pointed at before.
a_list[:] = ['foo', 'bar']
Calls the `__setitem__` method of the `a_list` object with a `slice` as the index, and a new `list` created in memory as the value.
`__setitem__` evaluates the `slice` to figure out what indexes it represents, and calls `iter` on the value it was passed. It then iterates over the object, setting each index within the range specified by the `slice` to the next value from the object. For `list`s, if the range specified by the `slice` is not the same length as the iterable, the `list` is resized. This allows you to do a number of interesting things, like delete sections of a list:
a_list[:] = [] # deletes all the items in the list, equivalent to 'del a_list[:]'
or inserting new values in the middle of a list:
a_list[1:1] = [1, 2, 3] # inserts the new values at index 1 in the list
However, with "extended slices", where the `step` is not one, the iterable must be the correct length:
>>> lst = [1, 2, 3]
>>> lst[::2] = []
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
ValueError: attempt to assign sequence of size 0 to extended slice of size 2
The main things that are different about slice assignment to `a_list` are:
- `a_list` must already point to an object
- That object is modified, instead of pointing `a_list` at a new object
- That object must support `__setitem__` with a `slice` index
- The object on the right must support iteration
- No name is pointed at the object on the right. If there are no other references to it (such as when it is a literal as in your example), it will be reference counted out of existence after the iteration is complete.
Problem
I see at many places the use of slice assignment for `list`s. I am able to understand its use when used with (non-default) indices, but I am not able to understand its use like: ``` a_list[:] = ['foo', 'bar'] ``` How is that different from ``` a_list = ['foo', 'bar'] ``` ?