变量在同一循环迭代中获取新值

Variable getting new value in same loop iteration

我 运行 遇到了一个问题,基本上我在循环顶部设置的一个变量在迭代结束前获得了一个新值。我该如何改变它才不会发生?我认为这与范围有关,但我不完全确定。相关代码和输出如下:

while not stop(old_centers, centers): #returns True when old centers == new ones
    
    old_centers = centers #setting old centers to centers, nothing fancy
    print 'old_centers', old_centers

    centers = label(points, centers)#calls the label func and assigns centers a new value

    print 'old centers ', old_centers, '\n new ones ', centers

    print '# of iterations: %d' % iterations
    iterations += 1

这是输出:

initial centers {'1': [1.193013180404786, 1.3490890491331484], '0': [0.10173245995124558, 0.2259745323785607], '2': [1.1969102753605907, 1.1584028826056012]}

old_centers {'1': [1.193013180404786, 1.3490890491331484], '0': [0.10173245995124558, 0.2259745323785607], '2': [1.1969102753605907, 1.1584028826056012]}

new centers in label {'1': [1.1646709311677974, 1.7595898757959954], '0': [0.23028481023828123, 0.9213541910575308], '2': [1.3055269036979071, 0.6867418777771471]}

old centers {'1': [1.1646709311677974, 1.7595898757959954], '0': [0.23028481023828123, 0.9213541910575308], '2': [1.3055269036979071, 0.6867418777771471]}

new ones {'1': [1.1646709311677974, 1.7595898757959954], '0': [0.23028481023828123, 0.9213541910575308], '2': [1.3055269036979071, 0.6867418777771471]}

# of iterations: 0

如您所见,我的 old_centers 变量在循环结束时被更改,强制 while 循环在第一次迭代后取消。起初,它正确地接收到初始字典,但是在调用 label 之后,它发生了变化,我不知道为什么。关于为什么会发生这种情况的任何提示?

您需要 copy.deepcopy,仅使用复制 不会 工作,因为您将列表作为值,因此任何列表中的任何更改也会在 [=14= 中更改]:

from copy import deepcopy

old_centers = deepcopy(centers)

old_centers = centers 创建对 centers 的引用,因此对 centers 的任何更改都会反映在 old_centers 中,因为两个对象都指向内存中的相同位置,两者都是其实是同一个对象。 c is d:

d = {1:2}
c = d
d[1] = 4
print(id(c),id(d))
print(c,d)
print(c is d)

140661961276040 140661961276040 # same id same objects
{1: 4} {1: 4}
True

现在复制:

from copy import deepcopy
d = {1: 2}
c = deepcopy(d) # create new object
d[1]= 4
print(id(c),id(d))
print(c,d)
print(c is d) 

140477200628872 140477200628360 # now two different id's two different objects
{1: 2} {1: 4}
False