Что такое поверхностная и глубокая копия (shallow copy vs deep copy)?

При поверхностной копии (shallow copy) создаётся новый контейнер, но вложенные объекты в нём — те же самые (копируются ссылки), поэтому изменение вложенного объекта в копии видно и в оригинале. При глубокой копии (deep copy) копируются и контейнер, и все вложенные объекты — копия полностью независима от исходной структуры.
Подробный ответ

Для изменяемых структур (списки, словари, вложенные коллекции) важно различать:

  1. простое присваивание b = a — не копия, обе переменные указывают на один и тот же объект;

  2. поверхностная копия — копируется только внешний контейнер;

  3. глубокая копия — копируется и контейнер, и все вложенные объекты.

Поверхностная копия (shallow copy)

При поверхностной копии создаётся новый контейнер, но его элементы — это те же объекты, что и в оригинале.

Сделать shallow copy можно так:

import copy

a = [[1, 2], [3, 4]]
b = a.copy()         # для списка
# или
b = list(a)
# или
b = copy.copy(a)

Поведение:

a = [[1, 2], [3, 4]]
b = a.copy()

b[0][0] = 99
print(a)  # [[99, 2], [3, 4]]
print(b)  # [[99, 2], [3, 4]]

Мы создали новый список b, но вложенные списки те же самые, поэтому изменение вложенного элемента отражается и в a.

Если заменить элемент верхнего уровня, ситуация другая:

a = [[1, 2], [3, 4]]
b = a.copy()

b[0] = [99, 2]
print(a)  # [[1, 2], [3, 4]]
print(b)  # [[99, 2], [3, 4]]

Здесь мы подменили ссылку в b[0] на новый список — оригинал не изменился.

Глубокая копия (deep copy)

При глубокой копии создаётся новый контейнер и рекурсивные копии всех вложенных объектов — копия полностью независима.

import copy

a = [[1, 2], [3, 4]]
c = copy.deepcopy(a)

c[0][0] = 99
print(a)  # [[1, 2], [3, 4]]
print(c)  # [[99, 2], [3, 4]]

Изменения в c не затрагивают a, потому что вложенные списки тоже были скопированы.

Формулировка для собеседования

Поверхностная копия создаёт новый контейнер, но вложенные объекты остаются общими — копируются только ссылки, поэтому изменение вложенных элементов видно и в оригинале. Глубокая копия рекурсивно копирует всю структуру, и получившаяся копия полностью независима: изменения в ней не влияют на исходные данные.

Оцени свой прогресс

Честно оцени своё понимание этого вопроса, чтобы мы могли построить твой учебный трек максимально эффективно.
Читать в блоге