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.]])]

      

+3


source to share


1 answer


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

      

+2


source







All Articles