Понимание изменчивости в 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]