为什么 list.append 在具有不同级别的 "for" 循环中表现不同

Why does list.append behave differently in the "for" loop with different levels

为什么会这样?我必须使用 numpy.array 的副本吗?但 它似乎适用于第一个代码。想不通为什么。

import numpy as np

n=3
h_all=[]
h=np.zeros((n,n))

for i in range(0, n):
    h = h + 1.
    h_all.append(h)          
print h_all

它给出

[array([[ 1.,  1.,  1.],
[ 1.,  1.,  1.],
[ 1.,  1.,  1.]]), array([[ 2.,  2.,  2.],
[ 2.,  2.,  2.],
[ 2.,  2.,  2.]]), array([[ 3.,  3.,  3.],
[ 3.,  3.,  3.],
[ 3.,  3.,  3.]])]

Which is good but if I code as

n=3
h_all=[]
h=np.zeros((n,n))
maxnum=3

for k in range(0, n):
    for i in range(0, n):
        for j in range(0, n):
            h[i,j] = h[i,j] + 1.
    h_all.append(h[:])          
print h_all
It becomes:
[array([[ 3.,  3.,  3.],
[ 3.,  3.,  3.],
[ 3.,  3.,  3.]]), array([[ 3.,  3.,  3.],
[ 3.,  3.,  3.],
[ 3.,  3.,  3.]]), array([[ 3.,  3.,  3.],
[ 3.,  3.,  3.],
[ 3.,  3.,  3.]])]
for k in range(0, n):
    ....
    h_all.append(h[:]) 

h_all 列表中放置指向 h 的指针。由于您在每个步骤就地修改 h,因此每次都会将相同的指针放置在 h_all 中。最后,h_all显示每个槽中h的当前值。

这是处理 Python 列表和字典时的常见问题。您必须在迭代的每个步骤附加一个副本,而不是可变对象。

要澄清这一点,请查看 id(h_all[0])id(h_all[1]);我希望他们是一样的。或者在循环后尝试 h +=1,观察 h_all 的值变化。

我应该补充一点,如果 h 是一个列表,h[:] 会创建一个副本,但如果它是一个数组,则不会。