在下面的代码中,我有一个填充的列表。 填充后,我再次访问它,但列表重置。
为什么会这样?
#Yonatan Oren 12/20/2013
#NIFTY GA Problem
from random import shuffle, randint, randrange
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def getX(self):
return self.x
def getY(self):
return self.y
def getDistance(self, point):
distance = (((point.getX() - self.x) ** 2) + ((point.getY() - self.y) ** 2)) ** (0.5)
return distance
class Value:
def __init__(self, pointsList):
self.pointsList = pointsList
self.fitness = 0
def getFitness(self):
#add up all of the distances
fitness = sum([a.getDistance(b) for a,b in zip(*[self.pointsList[i:] for i in range(2)])])
return fitness
def getPointsList(self):
return self.pointsList
def __lt__(self, other):
return self.getFitness() < other.getFitness()
class Environment:
def __init__(self):
self.values = []
def createNewEnvironment(self, pointsList):
self.pointsList = pointsList
#create 10 new organisms
for i in range(10):
org = Value(pointsList)
print org.getFitness()
self.values.append(org)
shuffle(pointsList)
for o in self.values:
print "point_listed: %s" % o.getFitness()
env = Environment()
env.createNewEnvironment([Point(0,0), Point(5,0), Point(10,0), Point(10,5), Point(10,10), Point(5,10), Point(0, 10), Point(0, 5), Point(0,0)])
这是输出:
40.0
75.3224755112
76.7924273619
56.1803398875
67.6831552862
84.7542230981
79.7542230981
57.3935433231
75.6120874744
70.6120874744
point_listed: 82.7160188343
point_listed: 82.7160188343
point_listed: 82.7160188343
point_listed: 82.7160188343
point_listed: 82.7160188343
point_listed: 82.7160188343
point_listed: 82.7160188343
point_listed: 82.7160188343
point_listed: 82.7160188343
point_listed: 82.7160188343
如您所见,所有值都重置为“82.7160188343”,我甚至都不知道 那个号码来自哪里。
有什么想法吗?
感谢。
答案 0 :(得分:3)
您正在创建一大堆共享相同pointsList
的值。
并不是他们的实例变量被重置,而是所有这些变量都是完全相同的值的名称,所以当你改变那个值时,他们都会看到它。
在此代码中:
self.pointsList = pointsList
#create 10 new organisms
for i in range(10):
org = Value(pointsList)
print org.getFitness()
self.values.append(org)
shuffle(pointsList)
...每个Value(pointsList)
构建一个具有相同Value
的新pointsList
对象。在Value.__init__
内,它不会复制该列表,只是这样做:
self.pointsList = pointsList
所以,他们最终只是指同一个名单。
您可能想要做以下三件事之一:
Value.__init__
内的列表(例如self.pointsList = pointsList[:]
)。Value.__init__
(例如org = Value(pointsList[:])
)。我认为其中第三个在您的用例中最干净。
我写了一个shuffled
函数,它返回一个新的混洗副本:
def shuffled(seq):
retval = list(seq)
shuffle(retval)
return retval
...所以你可以这样做:
self.pointsList = pointsList
#create 10 new organisms
for i in range(10):
pointsList = shuffled(pointsList)
org = Value(pointsList)
print org.getFitness()
self.values.append(org)