错误地在双`for`循环内索引

时间:2018-04-27 13:59:44

标签: python arrays for-loop indexing

我发布的是一个简化的代码版本,它可以重现我的问题:

import numpy as np

a1 = np.array([[0., (2/3)**(1/2), (1/3)**(1/2)],
           [-(1/2)**(1/2), -(1/6)**(1/2), (1/3)**(1/2)],
           [-(1/2)**(1/2), (1/6)**(1/2), -(1/3)**(1/2)],
           [(1/2)**(1/2), -(1/6)**(1/2), (1/3)**(1/2)],
           [(1/2)**(1/2), (1/6)**(1/2), -(1/3)**(1/2)],
           [0., -(2/3)**(1/2), -(1/3)**(1/2)]])

b1 = np.array([[-1. , 0., 0.],
           [-1/2, (3/4)**(1/2), 0.],
           [1/2, -(1/12)**(1/2), -(2/3)**(1/2)],
           [-1/2, -(3/4)**(1/2), 0.],
           [-1/2, -(1/12)**(1/2), -(2/3)**(1/2)],
           [0., (1/3)**(1/2), -(2/3)**(1/2)]])

a2 = np.array([[(1/2)**(1/2), (1/6)**(1/2), -(1/3)**(1/2)],
           [0., -(2/3)**(1/2), -(1/3)**(1/2)],
           [(1/2)**(1/2), -(1/6)**(1/2), (1/3)**(1/2)],
           [-(1/2)**(1/2), (1/6)**(1/2), -(1/3)**(1/2)],
           [0., (2/3)**(1/2), (1/3)**(1/2)],
           [-(1/2)**(1/2), -(1/6)**(1/2), (1/3)**(1/2)]])

b2 = np.array([[1/2 , -(3/4)**(1/2), 0.],
           [-1., 0., 0.],
           [-1/2, (1/12)**(1/2), (2/3)**(1/2)],
           [-1/2, -(3/4)**(1/2), 0.],
           [0., -(1/3)**(1/2), (2/3)**(1/2)],
           [1/2, (1/12)**(1/2), (2/3)**(1/2)]])


avector = [a1, a2]
bvector = [b1, b2]

cvector = [np.zeros([6, 3])]*2

for i in range(2):
    for j in range(6):
        cvector[i][j] = np.cross(avector[i][j], bvector[i][j])
        print(i, j, cvector[i][j])

print(cvector)

输出结果为:

0 0 [ 0.         -0.57735027  0.81649658]
0 1 [-0.5        -0.28867513 -0.81649658]
0 2 [-0.5       -0.8660254  0.       ]
0 3 [ 0.5        -0.28867513 -0.81649658]
0 4 [-0.5        0.8660254  0.       ]
0 5 [ 1.  0.  0.] 
1 0 [-0.5        -0.28867513 -0.81649658]
1 1 [ 0.          0.57735027 -0.81649658]
1 2 [-0.5       -0.8660254  0.       ]
1 3 [-0.5         0.28867513  0.81649658]
1 4 [ 1.  0. -0.]
1 5 [-0.5        0.8660254  0.       ]

[array([[-0.5       , -0.28867513, -0.81649658],
       [ 0.        ,  0.57735027, -0.81649658],
       [-0.5       , -0.8660254 ,  0.        ],
       [-0.5       ,  0.28867513,  0.81649658],
       [ 1.        ,  0.        , -0.        ],
       [-0.5       ,  0.8660254 ,  0.        ]]),
array([[-0.5       , -0.28867513, -0.81649658],
       [ 0.        ,  0.57735027, -0.81649658],
       [-0.5       , -0.8660254 ,  0.        ],
       [-0.5       ,  0.28867513,  0.81649658],
       [ 1.        ,  0.        , -0.        ],
       [-0.5       ,  0.8660254 ,  0.        ]])]

可以注意到0 0循环内计算的第一行for与矩阵cvector[0][0]不匹配。我希望他们相配。第六行0 5和矩阵cvector[0][0]也是如此。

如果您在第一个range(2)循环中将range(1)更改为for,您将看不到相同的行为,在我看来,这是正确的行为。

有谁知道为什么会这样?

1 个答案:

答案 0 :(得分:2)

使用editor.on创建cvector时,您不会创建2个[np.zeros([6, 3])]*2。第二个例子只是第一个视图。所以,np.array。因此,在循环中,当您再次为cvector[0] = cvector[1]执行时,会覆盖i=0计算。

相反,您可以创建两个独立的数组,如下所示:

i=1

它按预期工作:

cvector = [np.zeros([6, 3]), np.zeros([6, 3])]

考虑这个例子来说明第一个数组被覆盖的原因:

(0, 0, array([ 0.        , -0.57735027,  0.81649658]))
(0, 1, array([-0.5       , -0.28867513, -0.81649658]))
(0, 2, array([-0.5      , -0.8660254,  0.       ]))
(0, 3, array([ 0.5       , -0.28867513, -0.81649658]))
(0, 4, array([-0.5      ,  0.8660254,  0.       ]))
(0, 5, array([1., 0., 0.]))
(1, 0, array([-0.5       , -0.28867513, -0.81649658]))
(1, 1, array([ 0.        ,  0.57735027, -0.81649658]))
(1, 2, array([-0.5      , -0.8660254,  0.       ]))
(1, 3, array([-0.5       ,  0.28867513,  0.81649658]))
(1, 4, array([ 1.,  0., -0.]))
(1, 5, array([-0.5      ,  0.8660254,  0.       ]))

[array([[ 0.        , -0.57735027,  0.81649658],
       [-0.5       , -0.28867513, -0.81649658],
       [-0.5       , -0.8660254 ,  0.        ],
       [ 0.5       , -0.28867513, -0.81649658],
       [-0.5       ,  0.8660254 ,  0.        ],
       [ 1.        ,  0.        ,  0.        ]]),
 array([[-0.5       , -0.28867513, -0.81649658], 
       [ 0.        ,  0.57735027, -0.81649658],
       [-0.5       , -0.8660254 ,  0.        ],
       [-0.5       ,  0.28867513,  0.81649658],
       [ 1.        ,  0.        , -0.        ],
       [-0.5       ,  0.8660254 ,  0.        ]])]

注意在两种情况下如何覆盖第一个元素。