Копирование списка: copy(), срезы, list() и их отличия

Копирование списка: copy(), срезы, list() и их отличия Списки, словари, кортежи

Привет! Ты уже знаешь, что списки в Python изменяемы. И если ты присвоишь один список другому, они будут ссылаться на один и тот же объект в памяти. Изменение одного приведёт к изменению другого. Чтобы избежать этого, нужно создавать копии.

В этой статье мы разберём:

  • Чем отличается присваивание от копирования
  • Метод copy()
  • Срезы [:]
  • Конструктор list()
  • Поверхностное и глубокое копирование

Что нужно знать перед началом

Для этого урока тебе понадобится:

  • Установленный 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()
  • Разобрали поверхностное и глубокое копирование
  • Разобрали частые ошибки

КВИЗ

Что дальше?

Оцените статью
IMI-DS - PYTHON LERNEN
Содержание
Оглавление ×