Привет! Ты уже знаешь, что списки в Python изменяемы. И если ты присвоишь один список другому, они будут ссылаться на один и тот же объект в памяти. Изменение одного приведёт к изменению другого. Чтобы избежать этого, нужно создавать копии.
В этой статье мы разберём:
- Чем отличается присваивание от копирования
- Метод
copy() - Срезы
[:] - Конструктор
list() - Поверхностное и глубокое копирование
- Что нужно знать перед началом
- Основная часть
- Присваивание vs копирование
- Метод copy()
- Срезы ([:])
- Конструктор list()
- Сравнение методов
- Поверхностное копирование (shallow copy)
- Глубокое копирование (deep copy)
- Примеры из реальной жизни
- Задачи для закрепления
- Нюансы и подводные камни
- Изменяемые и неизменяемые элементы
- Копирование с помощью * (для одномерных списков)
- Производительность
- Частые ошибки и как их избежать
- Ошибка 1: Путаница между присваиванием и копированием
- Ошибка 2: Поверхностная копия для вложенных списков
- Ошибка 3: Забыл импортировать copy
- Шпаргалка
- Заключение
- КВИЗ
- Что дальше?
Что нужно знать перед началом
Для этого урока тебе понадобится:
- Установленный Python
- Базовое понимание списков
Совет: Важно различать присваивание (ссылку) и копирование. Присваивание не создаёт новый список, а только копирует ссылку.
Основная часть
Присваивание vs копирование
Присваивание (не копия):
original = [1, 2, 3]
copy = original
copy.append(4)
print(original) # [1, 2, 3, 4] — изменился!
print(copy) # [1, 2, 3, 4]Важно:
copy = original— это не копия. Это просто ещё одна ссылка на тот же список.
Метод copy()
original = [1, 2, 3]
copy = original.copy()
copy.append(4)
print(original) # [1, 2, 3] — не изменился
print(copy) # [1, 2, 3, 4]Совет:
copy()создаёт поверхностную копию списка.
Срезы ([:])
original = [1, 2, 3]
copy = original[:]
copy.append(4)
print(original) # [1, 2, 3]
print(copy) # [1, 2, 3, 4]Совет: Срезы
[:]создают полную копию списка. Это один из старых способов копирования.
Конструктор list()
original = [1, 2, 3]
copy = list(original)
copy.append(4)
print(original) # [1, 2, 3]
print(copy) # [1, 2, 3, 4]Совет:
list()принимает итерируемый объект и создаёт новый список. Для списков это создаёт копию.
Сравнение методов
| Метод | Синтаксис | Создаёт новый список? |
|---|---|---|
| Присваивание | b = a | ❌ Нет (только ссылка) |
copy() | b = a.copy() | ✅ Да |
| Срез | b = a[:] | ✅ Да |
list() | b = list(a) | ✅ Да |
Поверхностное копирование (shallow copy)
Все три метода (copy(), [:], list()) создают поверхностные копии.
original = [[1, 2], [3, 4]]
copy = original.copy()
copy[0][0] = 99
print(original) # [[99, 2], [3, 4]] — изменился!
print(copy) # [[99, 2], [3, 4]]Важно: Внутренние списки копируются по ссылке. Изменение вложенного списка влияет на оригинал
Глубокое копирование (deep copy)
Для полного копирования вложенных структур используй copy.deepcopy().
import copy
original = [[1, 2], [3, 4]]
deep_copy = copy.deepcopy(original)
deep_copy[0][0] = 99
print(original) # [[1, 2], [3, 4]] — не изменился
print(deep_copy) # [[99, 2], [3, 4]]Совет:
deepcopy()создаёт полностью независимую копию, включая все вложенные объекты.
Примеры из реальной жизни
Пример 1. Сохранение исходного списка:
data = [10, 20, 30, 40]
backup = data.copy()
# Изменяем данные, не затрагивая backup
data.append(50)
print(data) # [10, 20, 30, 40, 50]
print(backup) # [10, 20, 30, 40]Пример 2. Работа с матрицами:
matrix = [[1, 2], [3, 4]]
# Поверхностная копия — не подходит
shallow = matrix.copy()
shallow[0][0] = 99
print(matrix) # [[99, 2], [3, 4]]
# Глубокая копия — подходит
import copy
deep = copy.deepcopy(matrix)
deep[0][0] = 1
print(matrix) # [[99, 2], [3, 4]] — не изменилсяЗадачи для закрепления
Задача 1. Что выведет код?
a = [1, 2, 3]
b = a
b.append(4)
print(a)Задача 2. Что выведет код?
a = [1, 2, 3]
b = a.copy()
b.append(4)
print(a)Задача 3. В чём разница между copy() и deepcopy()?
Задача 4. Как скопировать список без использования copy()?
Задача 5. Что выведет код?
a = [[1, 2], [3, 4]]
b = a[:]
b[0][0] = 99
print(a)Ответы:
Задача 1.
# [1, 2, 3, 4] — b и a ссылаются на один списокЗадача 2.
# [1, 2, 3] — copy() создал новый списокЗадача 3.
# copy() — поверхностная копия
# deepcopy() — глубокая копия всех вложенных объектовЗадача 4.
# b = a[:] или b = list(a)Задача 5.
# [[99, 2], [3, 4]] — срез создал поверхностную копию,
# внутренние списки скопировались по ссылкеНюансы и подводные камни
Изменяемые и неизменяемые элементы
Если список содержит неизменяемые элементы (числа, строки), copy() работает как полная копия.
a = [1, 2, 3]
b = a.copy()
b[0] = 99
print(a) # [1, 2, 3] — не изменилсяЕсли список содержит изменяемые элементы (списки, словари), copy() копирует ссылки на них.
Копирование с помощью * (для одномерных списков)
a = [1, 2, 3]
b = a * 1 # Тоже копия
b.append(4)
print(a) # [1, 2, 3]
print(b) # [1, 2, 3, 4]Производительность
| Метод | Скорость |
|---|---|
copy() | Быстро |
[:] | Быстро |
list() | Быстро |
deepcopy() | Медленно (для больших структур) |
Частые ошибки и как их избежать
Ошибка 1: Путаница между присваиванием и копированием
Используй copy() или [:] для создания копии.
Ошибка 2: Поверхностная копия для вложенных списков
Используй deepcopy() для вложенных изменяемых объектов.
Ошибка 3: Забыл импортировать copy
import copy
Шпаргалка
| Что нужно | Как пишется |
|---|---|
| Присваивание | b = a |
| Копия списка | b = a.copy() |
| Копия через срез | b = a[:] |
| Копия через list() | b = list(a) |
| Глубокая копия | b = copy.deepcopy(a) |
Заключение
Сегодня мы:
- Научились копировать списки
- Разобрали
copy(),[:],list() - Разобрали поверхностное и глубокое копирование
- Разобрали частые ошибки








