При создании списка и присвоить его переменной, как
a = [1, 2, 3]
Вы создаете объект, а переменная а содержит ссылку на этот объект. Когда вы сделаете
b = a
Вы назначаете одну и ту же ссылку в b, так что теперь и a, и b указывают на ваш список. Поэтому, когда вы выполняете
b[0] = 5
Вы меняете тот же список.
Вы можете увидеть это в действии, используя функцию идентификатора(), которая возвращает адрес памяти объекта:
>>> a = [1, 2, 3]
>>> b = a
>>> id(a), id(b)
(140454191340720, 140454191340720)
Они идентичны. Дело в том, что a и b не являются самими списками, они указывают на список.
Когда вы делаете что-то вроде:
a = [1, 2, 3]
b = a
b = [2, 3, 4]
Вы первый назначены б ссылку на список, а указывает, но тогда вы назначаете новую ссылку на него.
Кстати, это может укусить вас в зад, когда вы делаете что-то вдоль линий
def foo (a=[]):
a.append(42)
return a
с аргумента указывает на тот же список на каждом вызове, если вы вызываете эту функцию в 5 раз без аргументов, список будет содержать 5x 42:
foo(); foo(); foo(); foo();
print(foo())
>>> [42, 42, 42, 42]
При выполнении последнего блока a не изменяется. Это именно то поведение, которого можно было бы ожидать (и надеяться на ...). – Blubber
Чтобы проверить, указана ли переменная, указывающая на адрес памяти, используйте функцию id(). В вашем случае - изначально id (a) и id (b) одинаковы. После выполнения b = [4,5,6] изменяется id (b). Таким образом, «b» указывает на другой адрес памяти, а «a» остается таким же. Simillarly проверить ваш второй сценарий. – rajpy
-1 Ты врешь – jamylak