это потому, что X
и Y
являются ссылками на тот же объект np.array([1,0,0])
это означает, что независимо от того, является ли вызов делается черезX
или Y
, результат будет тем же самым, но изменение ссылка одного, не имеет никакого эффекта.
Если вы пишете:
X = np.array([1,0,0])
Y = X
в основном то, что происходит в том, что есть две локальные переменныеX
и Y
, что относятся к тому же объекту. Таким образом, память выглядит следующим образом:
+--------+
Y -> |np.array| <- X
+--------+
|[1,0,0] |
+--------+
Теперь, если вы X[0] = 2
, которая в основном короткие для:
X.__setitem__(0,2)
так вы вызываете метод объекта. Так что теперь память выглядит следующим образом:
+--------+
Y -> |np.array| <- X
+--------+
|[2,0,0] |
+--------+
Однако, если вы пишете:
X = 2*X
первый 2*X
является оценивали.Теперь 2*X
короток для:
X.__rmul__(2)
(Python первый выглядит, если 2
поддерживает __mul__
для X
, но так как 2
поднимет NotImplementedException
), Python будет Откат к X.__rmul__
). Теперь X.__rmul__
не изменяется X
: он оставляет X
неповрежденным, но создает новый массив и возвращает его. X
ловит этот новый массив, который теперь ссылается на этот массив).
, который создает новый объект array
: array([4, 0, 0])
и затем X
ссылки на этот новый объект. Так что теперь память выглядит следующим образом:
+--------+ +--------+
Y -> |np.array| X ->|np.array|
+--------+ +--------+
|[2,0,0] | |[4,0,0] |
+--------+ +--------+
Но как вы можете видеть, Y
все еще ссылки на старый объект.
Здесь вы изменяете * локальную переменную 'X' *, это изменение не будет отражено в' Y', так как 'Y' даже не знает' X' существует. –
Спасибо, извините, я не был ясен на этом посту. Я изменяю строку X [0] = 2 на X = 2 * X в исходном коде выше. – SunnyIsaLearner
Поскольку назначение операции среза/индексации * мутирует структуру данных *, где, используя оператор '*', генерирует * новую * структуру данных. Также прочитайте и поймите это: http://nedbatchelder.com/text/names.html –