You are right that
B points to the original array and
A (at the end) is a transposed view of the array.
The key point here is something that trips up a lot of people: whenever you assign a new value to a variable by using
= with no indexing (e.g.,
A = <anything>), it causes that variable to point to a new location, but it doesn't alter the data previously held in that variable.
Here is an annotated version of what is happening:
A = np.array([[1,2,3],[4,5,6]])
# create the array [[1,2,3],[4,5,6]] at some location in memory
# (let's call it loc 1)
# point variable A to loc 1
B = A
# point variable B to the same location as A (loc 1)
A = A.T
# right-hand side:
# - get the array that A currently points to (from loc 1)
# - create a transposed view of this array and store the view
# somewhere in memory (let's call it loc 2)
# left-hand side: set variable A to point to loc 2
# Note: the `=` assignment does not alter the object at loc 1; instead,
# it points A to the new object that was created on the right-hand side
# Push the value -1 into position (0, 1) of the object that A
# currently points to, i.e., the view at loc 2. This updates
# the A view, but also propagates back to the original,
# un-transposed array at loc 1 (which B still points to).
# Note that the last two lines are equivalent to this:
X = A.T # doesn't transpose B
X[0,1]= -1 # propagates through view back to B
# i.e., the A.T could have been assigned to anything, e.g. a new
# variable X. When you do an assignment with `=`, it creates a new
# variable every time, even if it happens to have the same name as
# an old one, as in your case.
This is the general issue of changing mutable data and getting unexpected side effects. The easiest way to think about it is that a bare variable assignment (
A = <something>) never alters the underlying data that
A currently points to. Instead, it just causes
A to point somewhere new. On the other hand, assigning
A[index] = <something> or
A.attribute = <something> or using
A.data_altering_method(...) will alter the underlying object that A points to, in place, so anything else that points to the same object will also see the alteration.
In your case, the only thing you did that changed the underlying data was
A[0,1]= -1, and that did indeed propagate to
A = A.T did not alter the underlying data, it just pointed
A to something new (which happened to be a new view of the original data). So the change to the
A variable didn't propagate to
B. However, it is a little surprising that
A = A.T creates a view rather than a copy, so that later changes to
B. Your middle two lines are equivalent to
B.T[0,1] = -1.
These answers also help: