Reputation: 493
Why are the following objects behaving differently with regard to the [x] * n
operation?
I.e. why does the first operation (in[94]
) modify a single entry of the list, whereas the second operation (in[99]
) modify all the entries?
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.]])]
Upvotes: 3
Views: 50
Reputation: 7196
tl;dr : You implicitly made a shallow copy of the matrix when you were expecting 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 defined a
. Set b=a
and then changed a
to find the same change in b
even though I didn't touch b
.
By your line [x] * 10
, it made 10 shallow copies of x
. So, change in any one reflects on all others.
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 non-compound 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
Upvotes: 2