При изменении значения одной переменной меняется значение другой, причём ID у них разные

Делал я одну программку и столкнулся с одним неприятным багом. Проблема возникает в Python v3.9.0.

Есть у меня переменная i, которая принимает с каждой итерацией for значения элементов list1. Также есть переменная foo, которая хранит в себе копию i. Так вот, если изменить переменную foo, то i меняется вместе с ней, как будто имя foo и имя i ссылаются на одно и то же значение.

Мне нужно, чтобы foo не влияла на i, но при этом принимала её значение вначале цикла.

Вот код:

list1 = [                       #проблема возникает вроде только со списками такого типа - [ [[a1, …],[a2, …]], [[b1, …],[b2, …]], …]
    [[1, 2], [3, 4]]
]
for i in list1:
    foo = i[:]                  # имя foo ссылается на копию i
    # print(id(i1), id(foo))
    foo[1].append(9)            # после foo обязательно должен стоять [индекс какого-либо элемента foo], иначе баг не появится
    print(i)

Ожидаемый результат:

>>> [[1, 2], [3, 4]

Фактический результат:

>>> [[1, 2], [3, 4, 9]]

Ответы (1 шт):

Автор решения: Xander

Правильно, у foo и i айдишники будут разные. Зато если посмотрите id(foo[1]) и id(i[1]) - то эти айдишники будут одинаковыми.

При копировании создаётся новый список, а потом в него вставляются ссылки на элементы оригинала. Если хотите, чтобы и внутренние списки копировались по значению, то нужно использовать deepcopy

from copy import deepcopy

foo = deepcopy(i)  # вместо foo = i[:] 
→ Ссылка