Понимание изменчивости в Python

У меня есть этот фрагмент:

a = [1,2,3]
b = a
b = [4,5,6] # a doesnt change

и это:

a = [1,2,3]
b = a
b[0] = 5 # a also changes

Как bинициализация играет роль в определении изменчивости a?

1 ответ

Решение

Когда вы создаете список и назначаете его переменной, как

a = [1, 2, 3]

Вы создаете объект, а переменная a содержит ссылку на этот объект. Когда вы делаете

b = a

Вы назначаете одну и ту же ссылку в b, так что теперь и a, и b указывают на ваш список. Поэтому, когда вы выполняете

b[0] = 5

Вы измените тот же список.

Вы можете увидеть это в действии, используя функцию id(), которая возвращает адрес памяти объекта:

>>> a = [1, 2, 3]
>>> b = a
>>> id(a), id(b)
(140454191340720, 140454191340720)

Они одинаковые. Дело в том, что a и b не являются списками сами по себе, они указывают на список.

Когда вы делаете что-то вроде:

a = [1, 2, 3]
b = a
b = [2, 3, 4]

Сначала вы назначаете ссылку ba на список, на который указывает указатель, но затем вы присваиваете ему новую ссылку.

Кстати, это может укусить вас сзади, когда вы делаете что-то вроде

def foo (a=[]):
    a.append(42)
    return a

Поскольку аргумент a указывает на один и тот же список при каждом вызове, если вы вызываете эту функцию 5 раз без аргументов, список будет содержать 5x 42:

foo(); foo(); foo(); foo();
print(foo())
>>> [42, 42, 42, 42]
Другие вопросы по тегам