Ответ
Срез списка в Python (например, new_list = old_list[:]) создает поверхностную (shallow) копию.
Это означает, что создается новый объект-список, но он заполняется ссылками на те же самые объекты, которые содержались в оригинальном списке.
- Для неизменяемых объектов (числа, строки) это не имеет значения, так как их нельзя изменить.
- Для изменяемых объектов (списки, словари) изменение вложенного объекта в одной копии отразится и в другой, поскольку обе копии ссылаются на один и тот же вложенный объект.
Пример:
import copy
original_list = [[1, 2], [3, 4]]
# 1. Поверхностная копия (shallow copy) с помощью среза
shallow_copy = original_list[:]
# Изменяем вложенный список через поверхностную копию
shallow_copy[0][0] = 999
# Изменение отразилось и в оригинале, т.к. вложенный список - общий объект
print(f"Оригинал после shallow copy: {original_list}") # [[999, 2], [3, 4]]
print(f"Shallow copy: {shallow_copy}") # [[999, 2], [3, 4]]
# 2. Глубокая копия (deep copy) для сравнения
deep_copy = copy.deepcopy(original_list)
# Изменяем вложенный список через глубокую копию
deep_copy[0][1] = 777
# Изменение НЕ отразилось в оригинале, т.к. все объекты рекурсивно скопированы
print(f"Оригинал после deep copy: {original_list}") # [[999, 2], [3, 4]]
print(f"Deep copy: {deep_copy}") # [[999, 777], [3, 4]]
Вывод: Используйте срезы для быстрого копирования списков с неизменяемыми элементами. Если список содержит вложенные изменяемые структуры, для полной независимости копий используйте copy.deepcopy().
Ответ 18+ 🔞
Давай разберём эту дичь, которая в Питоне называется «копирование списков». Ситуация, в общем, пиздец как простая, но люди постоянно об неё обжигаются, как дураки о горячий чайник.
Смотри, есть у тебя список. Допустим, old_list. Ты такой: «О, ща сделаю копию, чтобы оригинал не трогать!» И пишешь new_list = old_list[:]. И думаешь, что ты молодец, блядь, и всё чики-пуки.
А вот нихуя! Это, сука, поверхностная копия (shallow copy). Что это значит на языке нормальных людей? Это значит, что ты создал новую коробку (новый список), но положил в неё не сами вещи, а бумажки с адресами, где эти вещи лежат.
- Если в коробке лежат кирпичи (числа, строки) — похуй. Кирпич не изменишь. Сделал копию бумажки «кирпич №1» — и хрен с ним, он так и останется кирпичом.
- А вот если в коробке лежат коробки поменьше (списки, словари) — вот тут начинается пиздец. Потому что обе твои бумажки (в оригинале и в копии) ведут к одной и той же маленькой коробке. Полез ты в копию, достал эту маленькую коробку и нахуярил туда мармеладок. А потом смотришь в оригинал — а там тоже мармеладки! Потому что коробка-то одна, блядь!
Пример, чтобы мозг не взорвался:
import copy
# Есть список, а в нём вложенные списки. Как матрёшка, епта.
original_list = [[1, 2], [3, 4]]
# 1. Делаем «умную» копию срезом (поверхностную)
shallow_copy = original_list[:]
# Лезем в копию и меняем что-то ВНУТРИ вложенного списка
shallow_copy[0][0] = 999 # Меняем не shallow_copy, а то, что внутри него!
# Смотрим, что получилось... Охуеть!
print(f"Оригинал после shallow copy: {original_list}") # [[999, 2], [3, 4]]
print(f"Shallow copy: {shallow_copy}") # [[999, 2], [3, 4]]
# Видишь? Оба списка показывают одно и то же дерьмо. Потому что внутренний список [[1,2]] — он один на двоих, как последняя шмотка в семье.
# 2. Теперь делаем копию по-взрослому, глубокую (deep copy)
deep_copy = copy.deepcopy(original_list)
# Опять хуярим изменение внутри копии
deep_copy[0][1] = 777
# И смотрим — магия, блядь!
print(f"Оригинал после deep copy: {original_list}") # [[999, 2], [3, 4]]
print(f"Deep copy: {deep_copy}") # [[999, 777], [3, 4]]
# Оригинал не тронут! Потому что `deepcopy` прошлась как терминатор и скопировала ВСЁ рекурсивно, до последней пылинки. Создала новые коробки для всех внутренних коробок.
Итог, ёпта:
Если у тебя список из примитивов (циферки, булевки, строки) — режь на здоровье, [:] хватит. А если там внутри сидят другие изменяемые штуки (списки в списках, словари и прочая хуйня) — не выёбывайся, бери copy.deepcopy(). Иначе потом будешь искать багу три дня, а она, сука, в этой строчке с копированием.