How does assignment work with list slices? How does assignment work with list slices? python python

How does assignment work with list slices?


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 theassigned sequence, thus changing the length of the target sequence, ifthe target sequence allows it. - source

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

# Tuple Unpackinga[0], a[1] = [4, 5]

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

>>> a[4, 5, 3]>>> a[-1], a[0] = [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.