Документ Python говорит, что нарезка списка возвращает новый список.
Теперь, если возвращается «новый» список, у меня возникают следующие вопросы, связанные с «Присвоением срезов»
a = [1, 2, 3]
a[0:2] = [4, 5]
print a
Теперь вывод будет:
[4, 5, 3]
- Как может то, что возвращает что-то, появиться в левой части выражения?
- Да, я прочитал документацию, и там говорится, что это возможно, поскольку теперь, когда нарезка списка возвращает «новый» список, почему изменяется исходный список? Я не могу понять механику этого.
a[0] = 4
бы сделали?=
, поэтому вместо того, чтобы отбрасывать это как недопустимый синтаксис, python превращает его во что-то более похожее на то, что вы могли ожидать. Поскольку у python нет ссылок, не получится изменить исходный список в результате среза. Вы получаете копию. Если вы предоставили дополнительную информацию о своем приложении, мы могли бы лучше помочь вам делать что-то «питоническим» способом. :)Ответы:
Вы путаете две разные операции, использующие очень похожий синтаксис:
1) нарезка:
Это делает копию фрагмента
a
и назначает егоb
.2) назначение срезов:
Это заменяет фрагмент
a
содержимымb
.Хотя синтаксис похож (я предполагаю, что это дизайн!), Это две разные операции.
источник
start=1
,stop=None
. Это позволит избежать копий и использовать ленивую оценку (в вашем случае ленивый доступ к исходному списку).Когда вы указываете
a
слева от=
оператора, вы используете обычное присвоение Python , которое изменяет имяa
в текущем контексте, чтобы указать на новое значение. Это не меняет предыдущее значение, на котороеa
указывалось.Указывая
a[0:2]
слева от=
оператора, вы сообщаете Python, что хотите использовать Slice Assignment . Назначение фрагментов - это специальный синтаксис для списков, в котором вы можете вставлять, удалять или заменять содержимое из списка:Вставка :
Удаление :
Замена :
Примечание:
Функция Slice Assignment аналогична функции Tuple Unpacking . Например,
a[0:1] = [4, 5]
эквивалентно:С помощью распаковки кортежей вы можете изменять непоследовательные списки:
Однако распаковка кортежа ограничивается заменой, так как вы не можете вставлять или удалять элементы.
До и после всех этих операций
a
- один и тот же точный список. Python просто предоставляет хороший синтаксический сахар для изменения списка на месте.источник
a[:] = some_list
эквивалентa = some_list[:]
илиa = some_list
?a[:] = some_list
устанавливает, что каждый элементa
изsome_list
. Выполнение любого из упомянутых вами действий изменит то, чтоa
есть. Например:a = [1, 2, 3]
b = a
a[:] = [4, 5, 6]
a is b
. Последняя строка будет иметь значение False, если она изменяетa
значение, а не изменяет его.Раньше я сталкивался с тем же вопросом, и он связан со спецификацией языка. Согласно заданиям-заявлениям ,
Если левая часть назначения - это подписка, Python вызовет
__setitem__
этот объект.a[i] = x
эквивалентноa.__setitem__(i, x)
.Если левая сторона присваивания - срез, Python также вызовет
__setitem__
, но с другими аргументами:a[1:4]=[1,2,3]
эквивалентноa.__setitem__(slice(1,4,None), [1,2,3])
Вот почему срез списка слева от '=' ведет себя иначе.
источник
Нарезая левую часть операции присваивания, вы указываете, какие элементы назначать.
источник