Вы правы, что нарезка не копирует элементы в списке. Тем не менее, он создает новый объект списка.
Ваш комментарий предполагает недопонимание:
# Attempting to modify the element at index 1
l[0:2][-1] = 10
Это не модификация элемента , это модификация список . Другими словами, это действительно «изменить список так, чтобы индекс 1 теперь указывал на число 10». Поскольку ваш срез создал новый список, вы просто изменяете этот новый список, чтобы он указывал на какой-то другой объект.
В своем комментарии к ответу oldrinb вы сказали:
Почему l[0:1]
и l[0:1][0]
разные? Разве они не должны ссылаться на один и тот же объект, то есть на первый элемент l
?
Помимо того, что l[0:1]
является списком, в то время как l[0:1][0]
является отдельным элементом, здесь опять то же недоразумение. Предположим, что some_list
является списком, а объект с индексом ix
равен obj
. Это:
some_list[ix] = blah
. , , это операция на some_list
. Объект obj
не задействован. Это может сбивать с толку, потому что это означает, что some_list[ix]
имеет слегка различную семантику в зависимости от того, на какой стороне присвоения он находится. Если вы делаете
blah = some_list[ix] + 2
. , .то вы действительно оперируете объектом внутри списка (т. е. он совпадает с obj + 2
). Но когда операция индексирования находится слева от назначения, она больше не включает в себя содержащийся объект, а только сам список.
Когда вы присваиваете индекс списка, вы модифицируете список , а не объект внутри него. Так что в вашем примере l[0]
совпадает с l[0:2][0]
, но это не имеет значения; поскольку ваша индексация является целью назначения, она изменяет список и не заботится о том, какой объект там уже находился.