← Все вопросы

Как сделать настоящую копию списка в Python, а не ссылку?

Задан 7 месяцев назад1.3к просмотров2 ответа
11

Сделал b = a, изменил b, а у меня изменился и a! Похоже, это одна и та же штука. Как сделать независимую копию списка, чтобы правки в одной переменной не трогали другую?

2 ответа

15
✓ Принятый ответ — помог автору

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

Чтобы сделать независимую (поверхностную) копию, есть несколько способов:

a = [1, 2, 3]

b = a[:]          # срез всего списка
c = a.copy()      # метод copy
d = list(a)       # через конструктор

Все три создают новый список. Теперь b.append(4) не тронет a.

Проверить, один ли это объект, можно оператором is:

b is a    # False — разные объекты

Важный нюанс — это поверхностная копия. Если внутри списка лежат вложенные списки или словари, копируются только ссылки на них, и вложенные объекты остаются общими:

a = [[1, 2], [3, 4]]
b = a.copy()
b[0].append(99)   # изменит и a[0]!

Для полностью независимой копии вложенных структур нужен deepcopy:

import copy
b = copy.deepcopy(a)

Правило: плоский список (числа, строки) — хватит a[:] или .copy(); список списков/словарей — deepcopy.

То же касается словарей: d2 = d1 это ссылка, а d2 = d1.copy() это копия.

5

Быстрый способ запомнить: присваивание = в Python никогда не копирует объекты, оно лишь привязывает новое имя к тому же объекту. Копию нужно создавать явно. Для списков это [:], .copy() или list(); для глубоких структур — copy.deepcopy(). Если переменная неизменяема (число, строка, кортеж), про копирование можно не думать — её всё равно нельзя поменять на месте.

Ваш ответ

Войдите, чтобы ответить на вопрос.