Ответ 1
Это вообще не проблема; это способ, которым массивы (и другие объекты) работают на Python.
Подумайте об этом так: массив, который вы создали в вашем примере кода, является объектом, который находится в каком-то месте в памяти. Но вы не можете использовать его в своей программе, говоря Python, где в памяти идти искать его; вы должны дать ему имя. Когда вы пишете
a = np.array([[1,2],[3,4]])
вы создаете массив и создаете имя a
, которое ссылается на него. С этого момента Python знает, что a
ссылается на "адрес памяти 0x123674283" (или что-то еще). Там есть внутренняя таблица в среде исполнения Python (называемая "таблицей символов", если я правильно помню), которая содержит всю эту информацию, поэтому после выполнения вышеуказанной строки кода Python эта таблица будет содержать
...,
'a' : 0x123674283,
...
Когда вы присваиваете значение одной переменной другой, например
b = a
Python не копирует весь массив, потому что если это большой массив, это займет много времени. Вместо этого он переходит в таблицу символов и копирует адрес памяти для a
в новую строку в таблице для b
. Таким образом, вы завершаетесь с
...,
'a' : 0x123674283,
...,
'b' : 0x123674283,
...
Итак, вы видите, a
и b
на самом деле ссылаются на одно и то же место в памяти, то есть на тот же объект. Любые изменения, внесенные вами в один, будут отражены в другом, так как они всего лишь два имени для одного и того же.
Если вы хотите сделать копию массива, вы должны вызвать метод, чтобы сделать это явно. Массивные массивы имеют метод copy
, который можно использовать только для этой цели. Поэтому, если вы пишете
b = a.copy()
тогда Python сначала сделает копию массива, то есть он отложит новую область памяти, скажем, по адресу 0x123904381, затем перейдет на адрес памяти 0x123674283 и скопирует все значения массива из последнего раздел памяти для первого. Таким образом, у вас есть тот же контент, который находится в двух разных местах в памяти.
...,
'a' : 0x123674283,
...,
'b' : 0x123904381,
...
Теперь, когда вы меняете один из элементов b
, это изменение не будет отображаться в a
, так как a
и b
больше не относятся к тому же разделу памяти компьютера. Поскольку есть две независимые копии данных массива, вы можете изменить один, не затрагивая другого.