Списки в Python невероятно хороши. Можно выполнять разные вещи, такие как:
+
;*
;+=
.Рассмотрим пример того, как оператор +
работает с объектом list
.
>>> lst = [3, 4, 5, 6, 7] >>> lst_copy = lst >>> lst = lst + [8, 9] >>> lst # [3, 4, 5, 6, 7, 8, 9] >>> lst_copy # [3, 4, 5, 6, 7]
Что произошло: создали список под названием lst
, затем создали новый список с именем lst_copy
, указав его на lst
. Затем изменили lst
, добавив к нему [8, 9]
. Как и ожидалось, оператор +
расширил список lst
создав новую последовательность, тогда как lst_copy
остался прежним.
В Python можно сократить выражения типа a = a + 1
до a += 1
. Вначале было сказано, что со списками можно использовать оператор +=
.
Итак, перепишем пример c использованием оператора присваивания на месте +=
:
>>> lst = [3, 4, 5, 6, 7] >>> lst_copy = lst >>> lst += [8, 9] >>> lst # [3, 4, 5, 6, 7, 8, 9] >>> lst_copy # [3, 4, 5, 6, 7, 8, 9] # Да ладно... Не может быть...
Что здесь произошло? Причина такого поведения в том, что, как и другие операторы Python, реализация оператора +=
определяется классом, который его реализует. То есть для оператора +=
класс списка определяет магический метод object.__iadd__(self, other)
, а способ его работы такой же, как у list.extend()
.
Так почему же был изменен список lst_copy
? Потому что это не фактическая копия lst
(lst.copy()
), а указатель на ячейку в памяти. То есть для списка list
(изменяемых последовательностей) оператор +=
изменяет ее, как говорится "на месте" - в памяти и не создает новую (итоговую) последовательность как с оператором +
.
>>> lst = [3, 4, 5, 6, 7] >>> lst_copy = lst >>> lst.extend([8, 9]) >>> lst # [3, 4, 5, 6, 7, 8, 9] >>> lst_copy # [3, 4, 5, 6, 7, 8, 9]