Изменятся ли остальные переменные, если одному из 27 переменных присвоить другое значение в Python?
Что проверяют
Понимаете ли вы, что переменная в Python это имя, привязанное к объекту, а не ячейка со значением. Число 27 подсказывает цепочку вида a = b = c = ... = [], где все имена смотрят на один объект. Следом обычно спрашивают, что изменится, если вместо присваивания вызвать метод или написать +=.
Как отвечать
Ответ: нет, не изменятся. Присваивание a = 5 только перепривязывает имя a к другому объекту, остальные 26 имён продолжают ссылаться на прежний. Это верно для любого типа, изменяемого и неизменяемого.
Все сразу меняются в другом случае, при мутации общего объекта:
- присваивание:
a = [1]создаёт новый список дляa, остальные видят старый; - мутация:
a.append(1),a[0] = 1,a.update(...)меняют сам объект, и изменение видно через все 27 имён; +=: для списка это мутация на месте через__iadd__, её увидят все. Уint,strиtupleтакого метода нет, и+=создаёт новый объект, как обычное присваивание.
Проверить общую ссылку можно через a is b или id(a) == id(b). Независимые объекты создают по отдельности: a, b = [], [] или генератором списка. Копию делают через copy.copy (поверхностная) или copy.deepcopy (глубокая, для вложенных структур).
Для неизменяемых объектов общая ссылка безопасна, поэтому a = b = 0 ничем не грозит: любое «изменение» числа всё равно даёт новый объект.
Где спотыкаются
Говорят, что для изменяемых типов присваивание меняет остальные переменные. Нет, их меняет только мутация, а присваивание не затрагивает другие имена никогда.
Попадаются на [[]] * 27. Получается список из 27 ссылок на один и тот же вложенный список, и append в любой из них виден во всех. Правильно писать [[] for _ in range(27)].
Сравнивают через is вместо == и делают выводы по кешу малых чисел: в CPython a is b для небольших int может дать True просто потому, что интерпретатор переиспользует объекты от -5 до 256. На поведение присваивания это не влияет.