Python: списки и их копирование

Я не могу объяснить следующее поведение:

l1 = [1, 2, 3, 4]
l1[:][0] = 888
print(l1) # [1, 2, 3, 4]
l1[:] = [9, 8, 7, 6]
print(l1) # [9, 8, 7, 6]

Кажется, что l1[:][0] относится к копии, тогда как l1[:] относится к самому объекту.

Ответ 1

l1[:][0] = 888 сначала берет срез всех элементов в l1 (l1[:]), который (в соответствии с семантикой списка) возвращает новый объект списка, содержащий все объекты в l1 - это мелкая копия l1.

Затем он заменяет первый элемент этого скопированного списка целым числом 888 ([0] = 888).

Затем скопированный список отбрасывается, потому что с ним ничего не делается.

Второй пример l1[:] = [9, 8, 7, 6] заменяет все элементы в l1 на те, что указаны в списке [9, 8, 7, 6]. Это назначение среза.

Ответ 2

Это вызвано функцией python, которая позволяет назначить список фрагменту другого списка, т.е.

l1 = [1,2,3,4]
l1[:2] = [9, 8]
print(l1)

установит l1 первые два значения в 9 и 8 соответственно. Аналогично,

l1[:] = [9, 8, 7, 6]

присваивает новые значения всем элементам l1.


Подробнее о назначениях в в документах.