基本类型(int)和复杂类型(np.ndarray)之间的行为差​​异

时间:2015-05-15 00:18:38

标签: python numpy

为什么以下对象在[x] * n操作方面表现不同? 即为什么第一个操作(in[94])修改列表的单个条目,而第二个操作(in[99])修改 all 条目?

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

1 个答案:

答案 0 :(得分:2)

tl; dr:当您期待深层复制时,您隐式地制作了矩阵的shallow copy Documentation

考虑以下代码:

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

另外:

In [46]: id(a)
Out[46]: 140529107552512

In [47]: id(b)
Out[47]: 140529107552512

我定义了a。设置b=a,然后更改a以查找b中的相同更改,即使我没有触及b

通过您的第[x] * 10行,它制作了10份x的浅份副本。因此,任何一个人的变化都反映在所有其他人身上

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

对于intany 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