← Все вопросы

Почему список меняется неожиданно, хотя я его не трогал? (ссылки в Python)

Задан 9 месяцев назад943 просмотров2 ответа
10

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

2 ответа

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

Дело в том, что b = a не создаёт копию списка — это просто второе имя для того же самого объекта в памяти. Списки в Python изменяемые, и обе переменные ссылаются на один список, поэтому меняя один, вы меняете «оба».

a = [1, 2, 3]
b = a            # b и a — это один и тот же список
b.append(4)
print(a)         # [1, 2, 3, 4] — изменился и a!

Как сделать настоящую (поверхностную) копию:

b = a.copy()        # или b = a[:] или b = list(a)
b.append(4)
print(a)            # [1, 2, 3] — a не тронут

Важный нюанс: copy() копирует только верхний уровень. Если внутри списка лежат вложенные списки/словари, они всё ещё общие:

a = [[1, 2], [3, 4]]
b = a.copy()
b[0].append(99)
print(a)            # [[1, 2, 99], [3, 4]] — вложенный список общий!

Для полностью независимой копии используйте глубокое копирование:

import copy
b = copy.deepcopy(a)

Правило: присваивание (=) делает алиас (второе имя), а не копию. Для копии нужен .copy(), срез [:] или deepcopy для вложенных структур.

6

То же самое работает и с функциями: если передать список в функцию и изменить его там (через append, [i] = ...), изменится оригинал, потому что внутрь попадает та же ссылка. Чтобы не портить исходный список, делайте копию в начале функции: data = data.copy().

Ваш ответ

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