我在python中运行以下代码:
w= np.random.rand(3)
w_old=np.zeros((3,))
while (np.linalg.norm(w - w_old)) / np.linalg.norm(w) > 1e-5:
w_old=w
print w
print w_old
w[0]-=eta*dE1i
w[1]-=eta*dE2i
w[2]-=eta*dE3i
print w
print w_old
印刷品的结果是:
[ 0.22877423 0.59402658 0.16657174]
[ 0.22877423 0.59402658 0.16657174]
和
[ 0.21625852 0.5573612 0.123111 ]
[ 0.21625852 0.5573612 0.123111 ]
我想知道为什么w_old
的价值发生了变化?回到while循环的开头后不应该更新吗?我该如何解决这个问题?
答案 0 :(得分:2)
只需使用
w_old = w
不复制w
,使用=
只是告诉python你想要存储在w
中的任何名称的其他名称。因此,w
的每个就地更改也会更改w_old
。如果您需要更多详细信息Ned Batchelder: "Facts and myths about Python names and values"
您可以使用copy
方法显式复制numpy数组:
w_old = w.copy()
答案 1 :(得分:0)
为了清楚起见,变量是独立的,所以:
a=5
b=a
如果您更改a
或b
,会正常工作。但是列表和词典不能以相同的方式复制,所以:
a=[1,2]
b=a
a[0]=100
print(b[0])
会给你100,因为现在a
和b
是两个名字相同的东西。所以在使用前建议
w_old = w.copy()
相反,w_old
是一个新列表,而不仅仅是旧列表的另一个名称。
答案 2 :(得分:0)
Python中的赋值语句不复制对象,它们创建 目标和对象之间的绑定。
所以,解决方案是
对于可变或包含可变项的集合,副本为 有时需要,所以一个人可以更改一个副本而无需更改 其他。
因此,使用copy()
我们可以将代码重写为
import numpy as np
w= np.random.rand(3)
w_old=np.zeros((3,))
while (np.linalg.norm(w - w_old)) / np.linalg.norm(w) > 1e-5:
w_old=w.copy()
print(w)
print(w_old)
w[0]-=0.01
w[1]-=0.01
w[2]-=0.01
print(w)
print(w_old)
并获得
[0.79666571 0.82305671 0.41167625]
[0.79666571 0.82305671 0.41167625]
和
[0.78666571 0.81305671 0.40167625]
[0.79666571 0.82305671 0.41167625]