Reputation: 6194
After defining an arrray a
with zeros, I can create a view to the leftmost column with the following function:
a = np.zeros((5, 5))
a_left_col = a[:, 0]
a_left_col[:] = 2.
which prints for a
:
array([[2., 0., 0., 0., 0.],
[2., 0., 0., 0., 0.],
[2., 0., 0., 0., 0.],
[2., 0., 0., 0., 0.],
[2., 0., 0., 0., 0.]])
If I subsequently reinitialize a
with
a = np.zeros((5, 5))
then the view still exists, but it refers to nothing anymore. How does Python handle the situation if I do a_left_col[:] = 2
again? Is this undefined behavior like in C or C++, or does Python handle it properly, and if so, why doesn't it throw an error?
Upvotes: 1
Views: 32
Reputation: 23647
The original object still exists because it is referenced by the view. (Although it can be no longer accessed through variable a
.)
Let's have a detailed look at the object's reference counts:
import sys
import numpy as np
a = np.zeros((5, 5))
print(sys.getrefcount(a)) # 2
a_left_col = a[:, 0]
print(sys.getrefcount(a)) # 3
print(sys.getrefcount(a_left_col.base)) # 3
print(a_left_col.base is a) # True
a = np.ones((5, 5))
print(sys.getrefcount(a_left_col.base)) # 2
Note that a_left_col.base
is the reference to the original array. When we reassing a
The reference count on the object decreases but it still exists because it is reachable throgh a_left_col
.
Upvotes: 1
Reputation: 1535
Behaviour is not undefined. You are merely creating a new object a
. The old one is not deallocated, but still exists in memory, since a_left_col still references it. Once you reinitialize a_left_col
, the original array can be deallocated.
Upvotes: 1