Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
191 views
in Technique[技术] by (71.8m points)

python - What is the difference between slice assignment that slices the whole list and direct assignment?

I see at many places the use of slice assignment for lists. 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']

?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
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 lists, 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:

  1. a_list must already point to an object
  2. That object is modified, instead of pointing a_list at a new object
  3. That object must support __setitem__ with a slice index
  4. The object on the right must support iteration
  5. 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.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...