Ответ
copy() создает поверхностную (shallow) копию объекта. Копируются только ссылки на вложенные изменяемые объекты (например, списки внутри списка), поэтому изменения во вложенных объектах оригинала отразятся на копии.
deepcopy() создает глубокую копию, рекурсивно копируя сам объект и все объекты, на которые он ссылается, создавая полностью независимую копию.
Пример, демонстрирующий разницу:
import copy
original = [[1, 2], [3, 4]]
shallow = copy.copy(original)
deep = copy.deepcopy(original)
# Изменяем вложенный список в оригинале
original[0][0] = 99
print(shallow) # [[99, 2], [3, 4]] - изменился, так как ссылается на тот же вложенный список
print(deep) # [[1, 2], [3, 4]] - не изменился, это полностью независимая копия
Когда что использовать:
copy()— когда объект содержит только неизменяемые элементы (числа, строки, кортежи) или когда вам намеренно нужно разделять вложенные изменяемые данные. Работает быстрее.deepcopy()— когда необходимо создать полную, независимую клон-копию сложного объекта со вложенными списками, словарями и т.д. Требует больше ресурсов.
Ответ 18+ 🔞
Давай разберём этот вопрос, чтобы голова не болела. Представь, что у тебя есть коробка с бумажками, на которых написаны номера других коробок. Это и есть наши объекты с вложенными списками.
copy() — это как сфоткать коробку на телефон.
Ты видишь те же самые бумажки с номерами. Если кто-то потом залезет в одну из тех коробок, на которую есть бумажка, и что-то там поменяет, то на твоей фотографии это тоже будет видно. Потому что бумажка-ссылка одна и та же. Это поверхностное копирование, ёпта.
deepcopy() — это как взять пустые коробки и заново, с нуля, переписать ВСЕ бумажки, да ещё и заглянуть в каждую указанную коробку, чтобы скопировать и её содержимое.
Получается абсолютно независимая копия. Что в оригинале творится — уже похуй. Это глубокая копия.
Пример, чтобы совсем мозг не взорвался:
import copy
original = [[1, 2], [3, 4]] # Коробка, в ней две бумажки с номерами других коробок.
shallow = copy.copy(original) # Просто сфоткали.
deep = copy.deepcopy(original) # Пересобрали всё заново с нуля.
# Теперь лезем в оригинал и меняем содержимое ВЛОЖЕННОЙ коробки.
original[0][0] = 99 # В первой внутренней коробке меняем 1 на 99.
print(shallow) # [[99, 2], [3, 4]] - Опа, а на фотке-то тоже поменялось! Потому что бумажка ведёт на ту же самую коробку.
print(deep) # [[1, 2], [3, 4]] - А тут нихуя не изменилось. Полная независимость, как Швейцария.
Так когда что брать, чтобы не обосраться?
copy()— бери, когда у тебя объект простой, как валенок: только числа, строки, кортежи (они неизменяемые, с ними не выйдет конфуза). Или когда тебе нарочно нужно, чтобы вложенные штуки менялись одновременно. Работает быстро, без лишней возни.deepcopy()— вот это уже тяжёлая артиллерия. Пускай в ход, когда у тебя там целое гнездо: списки в словарях, словари в списках, и всё это ещё друг на друга ссылается. Нужно сделать полного клона, чтобы он жил своей жизнью. Да, он жрёт память и время, зато потом не будет сюрпризов, что «оно само поменялось». Волнение ебать, но терпения ноль — лучше сразуdeepcopy, если сомневаешься.