我正在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循环的开头后不应该更新吗?我该如何解决这个问题?
只是使用
w_old = w
不复制w
,使用=
只是告诉python你想要w
中存储的任何内容的另一个名称。因此,对w
的每次就地更改也会更改w_old
。有一篇非常好的博客文章,如果你想了解更多细节 Ned Batchelder:"关于Python名称和值的事实和神话">
您可以显式复制 numpy 数组,例如,使用copy
方法:
w_old = w.copy()
为了澄清一下,变量是独立的,因此:
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
是一个新列表,而不仅仅是旧列表的另一个名称。
只是为了总结上面的答案,根据python文档
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]