Как работают copy и deepcopy в Python — разбор примера
@python_quizРазберем этот квиз
Коротко: shallow copy (copy) копирует только внешний контейнер, а вложенные объекты остаются общими. deepcopy рекурсивно дублирует всё дерево объектов. Ниже разберём заданный код пошагово и покажем, какой будет вывод и почему.
Условие (фрагмент кода)

Пошаговый разбор состояния переменных
- Инициализация:
- x = [[1], [2]]
- len(x) == 2
- x[0] -> [1], x[1] -> [2]
y = copy(x)
- copy создаёт новый (внешний) список y, но элементы (вложенные списки) копируются по ссылке.
- y — новый объект, но y[0] и x[0] — одна и та же ссылка на список [1].
z = deepcopy(x)
- deepcopy создаёт полностью независимую копию: и внешний список, и все вложенные списки.
- z[0] — отдельный список, равный по значению [1], но не тот же объект.
- x[0].append(99)
- Изменяем вложенный список, на который ссылаются x[0] и y[0].
- Поэтому и x[0], и y[0] становятся [1, 99].
- z[0] остаётся [1] (независимая копия).
- y.append([3])
- Добавляем новый элемент в внешний список y.
- Это не затрагивает x и z — только len(y) увеличивается.
Итоговые длины и значение z[0]:
- len(x) = 2 (внешний список x не менялся после создания),
- len(y) = 3 (в y добавили новый элемент),
- len(z) = 2 (z — полная копия исходного x, не изменялся),
- z[0] = [1] (вложний список в z не затронут).
Демонстрация с id для наглядности

Ожидаемый вывод (консоль):

Анализ вариантов ответов из квиза
- Любая опция, где внешняя длина x равна 3, неверна: мы не добавляли элементы в x, добавление происходило в y.
- Значение z[0] должно быть [1], потому что deepcopy сделал глубокую копию вложенных списков.
- Единственный вариант, совпадающий с выводом программы, — вариант, в котором вывод выглядит как:
2 3 2 [1]
Вывод
Поверхностное копирование копирует только сам контейнер (новый объект-список), но не рождает новые вложенные объекты — они остаются общими между оригиналом и поверхностной копией. Глубокое копирование создаёт полную независимую копию. В приведённом примере это приводит к выводу: 2 3 2 [1].