为什么 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[:]
会创建一个副本,但如果它是一个数组,则不会。
为什么会这样?我必须使用 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[:]
会创建一个副本,但如果它是一个数组,则不会。