# How does assignment work with list slices?

Posted on

Problem :

Python docs says that slicing a list returns a new list.
Now if a “new” list is being returned I’ve the following questions related to “Assignment to slices”

``````a = [1, 2, 3]
a[0:2] = [4, 5]
print a
``````

Now the output would be:

``````[4, 5, 3]
``````
1. How can something that is returning something come on the left side of expression?
2. Yes, I read the docs and it says it is possible, now since slicing a list returns a “new” list, why is the original list being modified? I am not able to understand the mechanics behind it.

Solution :

You are confusing two distinct operation that use very similar syntax:

1) slicing:

``````b = a[0:2]
``````

This makes a copy of the slice of `a` and assigns it to `b`.

2) slice assignment:

``````a[0:2] = b
``````

This replaces the slice of `a` with the contents of `b`.

Although the syntax is similar (I imagine by design!), these are two different operations.

When you specify `a` on the left side of the `=` operator, you are using Python’s normal assignment, which changes the name `a` in the current context to point to the new value. This does not change the previous value to which `a` was pointing.

By specifying `a[0:2]` on the left side of the `=` operator, you are telling Python you want to use slice assignment. Slice assignment is a special syntax for lists, where you can insert, delete, or replace contents from a list:

Insertion:

``````>>> a = [1, 2, 3]
>>> a[0:0] = [-3, -2, -1, 0]
>>> a
[-3, -2, -1, 0, 1, 2, 3]
``````

Deletion:

``````>>> a
[-3, -2, -1, 0, 1, 2, 3]
>>> a[2:4] = []
>>> a
[-3, -2, 1, 2, 3]
``````

Replacement:

``````>>> a
[-3, -2, 1, 2, 3]
>>> a[:] = [1, 2, 3]
>>> a
[1, 2, 3]
``````

Note:

The length of the slice may be different from the length of the
assigned sequence, thus changing the length of the target sequence, if
the target sequence allows it. – source

Slice assignment provides similar function to tuple unpacking. For example, `a[0:1] = [4, 5]` is equivalent to:

``````# Tuple Unpacking
a, a = [4, 5]
``````

With tuple unpacking, you can modify non-sequential lists:

``````>>> a
[4, 5, 3]
>>> a[-1], a = [7, 3]
>>> a
[3, 5, 7]
``````

However, tuple unpacking is limited to replacement, as you cannot insert or remove elements.

Before and after all these operations, `a` is the same exact list. Python simply provides nice syntactic sugar to modify a list in-place.

I came across the same question before and it’s related to the language specification. According to assignment-statements,

1. If the left side of assignment is subscription, Python will call `__setitem__` on that object. `a[i] = x` is equivalent to `a.__setitem__(i, x)`.

2. If the left side of assignment is slice, Python will also call `__setitem__`, but with different arguments:
`a[1:4]=[1,2,3]` is equivalent to
`a.__setitem__(slice(1,4,None), [1,2,3])`

That’s why list slice on the left side of ‘=’ behaves differently.

By slicing on the left hand side of an assignment operation, you are specifying which items to assign to.

When you did `a[0:2] = [4,5]`, you assigned the the left hand side of the `=` (the slice `a[0:2]`) the value on the right side of the `=`, `[4,5]`.