python:while循环中的变量

时间:2017-08-18 00:15:14

标签: python while-loop

我在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循环的开头后不应该更新吗?我该如何解决这个问题?

3 个答案:

答案 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
如果您更改ab

会正常工作。但是列表和词典不能以相同的方式复制,所以:

a=[1,2]
b=a
a[0]=100
print(b[0])

会给你100,因为现在ab是两个名字相同的东西。所以在使用前建议

w_old = w.copy()

相反,w_old是一个新列表,而不仅仅是旧列表的另一个名称。

答案 2 :(得分:0)

根据python documentation

来总结以上答案
  

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]