Reputation: 73
I'm running into an issue where basically a variable I set at the top of the loop is getting a new value before the end of the iteration. How do I change this so it doesn't happen? I think it has something to do with scope, but I'm not entirely sure. Relevant code and output below:
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
And here is the output:
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
As you can see, my old_centers variable is changed by the end of the loop, forcing the while loop to cancel after the first iteration. At first, it correctly receives the initial dict, but after label is called, it changes and I have no idea why. Any tips on why this is happening?
Upvotes: 0
Views: 88
Reputation: 180411
You need to copy.deepcopy
,just using copy will not work as you have lists as values so any changes in any list will also change in old_centers
:
from copy import deepcopy
old_centers = deepcopy(centers)
old_centers = centers
creates a reference to centers
so any changes to centers
are reflected in old_centers
as both objects are pointing to the same location in memory, both are in fact the same object. 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
Now copy:
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
Upvotes: 1