Ответ 1
a_list = ['foo', 'bar']
Создает новый list
в памяти и указывает на него имя a_list
. Не имеет значения, на что раньше указывал a_list
.
a_list[:] = ['foo', 'bar']
Вызывает метод __setitem__
объекта a_list
с slice
в качестве индекс и новый list
, созданный в памяти в качестве значения.
__setitem__
оценивает slice
, чтобы выяснить, какие индексы он представляет, и вызывает iter
значение, которое оно было передано. Затем он выполняет итерацию по объекту, устанавливая каждый индекс в диапазоне, указанном slice
, на следующее значение от объекта. Для list
s, если диапазон, указанный slice
, не такой же длины, как и итерабельный, размер list
изменяется. Это позволяет вам делать несколько интересных вещей, например удаление разделов списка:
a_list[:] = [] # deletes all the items in the list, equivalent to 'del a_list[:]'
или вставка новых значений в середине списка:
a_list[1:1] = [1, 2, 3] # inserts the new values at index 1 in the list
Однако с "расширенными срезами", где step
не один, итерабельность должна быть правильной длины:
>>> 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
Основными вещами, которые отличаются от назначения slice a_list
, являются:
-
a_list
должен указывать на объект - Этот объект изменен, вместо указания
a_list
на новый объект - Этот объект должен поддерживать
__setitem__
с индексомslice
- Объект справа должен поддерживать итерацию
- На объекте справа не указывается имя. Если нет других ссылок на него (например, когда это буква, как в вашем примере), после завершения итерации это будет считаться ссылкой из.