В документах Python говорится, что при разделении списка возвращается новый список. Теперь, если возвращается "новый" список, у меня возникают следующие вопросы, связанные с "Назначением фрагментам"
a = [1, 2, 3] a[0:2] = [4, 5] print a
Теперь результат будет следующим:
[4, 5, 3]
Как что-то, возвращающее что-то, может оказаться в левой части выражения?
Да, я прочитал документы, и там говорится, что это возможно, теперь, поскольку фрагмент списка возвращает "новый" список, почему изменяется исходный список? Я не могу понять механику, стоящую за этим.
Переведено автоматически
Ответ 1
Вы путаете две разные операции, которые используют очень похожий синтаксис:
1) нарезка:
b = a[0:2]
Это создает копию фрагмента из a и присваивает его b.
2) назначение фрагментов:
a[0:2] = b
Это заменяет фрагмент a на содержимое b.
Хотя синтаксис похож (я полагаю, по дизайну!), это две разные операции.
Ответ 2
Когда вы указываете a в левой части = оператора, вы используете обычное присваивание в Python, которое изменяет имя a в текущем контексте, указывая на новое значение. Это не изменяет предыдущее значение, на которое a указывало.
Указывая a[0:2] в левой части = оператора, вы сообщаете Python, что хотите использовать присваивание фрагментов. Назначение фрагментов - это специальный синтаксис для списков, в котором вы можете вставлять, удалять или заменять содержимое из списка:
>>> a [-3, -2, -1, 0, 1, 2, 3] >>> a[2:4] = [] >>> a [-3, -2, 1, 2, 3]
Замена:
>>> a [-3, -2, 1, 2, 3] >>> a[:] = [1, 2, 3] >>> a [1, 2, 3]
Примечание:
Длина фрагмента может отличаться от длины назначенной последовательности, таким образом изменяя длину целевой последовательности, если целевая последовательность это позволяет. - Источник
Назначение фрагментов предоставляет функцию, аналогичную распаковке кортежей. Например, a[0:1] = [4, 5] эквивалентно:
# Tuple Unpacking a[0], a[1] = [4, 5]
С помощью распаковки кортежей вы можете изменять непоследовательные списки:
>>> a [4, 5, 3] >>> a[-1], a[0] = [7, 3] >>> a [3, 5, 7]
Однако распаковка кортежа ограничивается заменой, поскольку вы не можете вставлять или удалять элементы.
До и после всех этих операций a это один и тот же точный список. Python просто предоставляет хороший синтаксический сахар для изменения списка на месте.
Ответ 3
Я сталкивался с тем же вопросом раньше, и он связан со спецификацией языка. Согласно assignment-statements,
Если в левой части присваивания указано subscription, 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])
Вот почему фрагмент списка в левой части '=' ведет себя по-другому.
Ответ 4
Выделяя фрагменты в левой части операции присваивания, вы указываете, каким элементам присваивать.