Difference in behavior between base type (int) and complex type (np.ndarray)
Why do the following objects behave differently with respect to the operation [x] * n
? That is, why does the first operation ( in[94]
) change one entry in the list, while the second operation ( in[99]
) changes all the records?
In [91]: x = 8
In [92]: y = [x] * 10
In [93]: y
Out[93]: [8, 8, 8, 8, 8, 8, 8, 8, 8, 8]
In [94]: y[1] = 4
In [95]: y
Out[95]: [8, 4, 8, 8, 8, 8, 8, 8, 8, 8]
In [96]: x = np.zeros(shape=(3,3))
In [97]: y = [x] * 10
In [98]: y
Out[98]:
[array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]]), array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]]), array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]]), array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]]), array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]]), array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]]), array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]]), array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]]), array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]]), array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]])]
In [99]: y[1][1,2] = 5
In [100]: y
Out[100]:
[array([[ 0., 0., 0.],
[ 0., 0., 5.],
[ 0., 0., 0.]]), array([[ 0., 0., 0.],
[ 0., 0., 5.],
[ 0., 0., 0.]]), array([[ 0., 0., 0.],
[ 0., 0., 5.],
[ 0., 0., 0.]]), array([[ 0., 0., 0.],
[ 0., 0., 5.],
[ 0., 0., 0.]]), array([[ 0., 0., 0.],
[ 0., 0., 5.],
[ 0., 0., 0.]]), array([[ 0., 0., 0.],
[ 0., 0., 5.],
[ 0., 0., 0.]]), array([[ 0., 0., 0.],
[ 0., 0., 5.],
[ 0., 0., 0.]]), array([[ 0., 0., 0.],
[ 0., 0., 5.],
[ 0., 0., 0.]]), array([[ 0., 0., 0.],
[ 0., 0., 5.],
[ 0., 0., 0.]]), array([[ 0., 0., 0.],
[ 0., 0., 5.],
[ 0., 0., 0.]])]
source to share
tl; dr: You implicitly made a shallow copy of the matrix when you expected a deep copy. Documentation
Consider the following bit of code:
In [38]: import numpy
In [39]: a = numpy.eye(2)
In [40]: a
Out[40]:
array([[ 1., 0.],
[ 0., 1.]])
In [41]: b = a
In [42]: b
Out[42]:
array([[ 1., 0.],
[ 0., 1.]])
In [43]: a[0,0] = 2
In [44]: a
Out[44]:
array([[ 2., 0.],
[ 0., 1.]])
In [45]: b
Out[45]:
array([[ 2., 0.],
[ 0., 1.]])
Also:
In [46]: id(a)
Out[46]: 140529107552512
In [47]: id(b)
Out[47]: 140529107552512
I have identified a
. Install b=a
and then modify a
to find the same change in b
, although I haven't touched b
.
[x] * 10
She made 10 small copies along your line x
. Thus, a change in anyone is reflected in everyone else.
In [90]: x = np.zeros(shape=(3,3))
In [95]: y = [x] * 10
In [96]: id(y[0])
Out[96]: 140529110575952
In [97]: id(y[1])
Out[97]: 140529110575952
In [98]: y[1][1,2] = 5
In [99]: id(y[0])
Out[99]: 140529110575952
In [100]: id(y[1])
Out[100]: 140529110575952
This is not a problem for int
or any other unconsolidated type .
In [105]: x = 0
In [106]: y = [x] * 10
In [107]: y
Out[107]: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
In [108]: y[1] = 2
In [109]: y
Out[109]: [0, 2, 0, 0, 0, 0, 0, 0, 0, 0]
In [110]: id(y[0])
Out[110]: 140529069263200
In [111]: id(y[1])
Out[111]: 140529069263152
source to share