Python对象引用

时间:2013-11-05 23:55:25

标签: python object

我的目标是创建一个旅游列表。每次旅行都是一个清单。

此代码的问题在于,在循环结束时,列表tours不是不同的混乱游览列表,而是列表中添加到列表的最后一个游览。我想这与Python对象引用有关,但我不知道如何改变它。我试过del tour,但无济于事。

def initialisePopulation(self, cities):
    tours = []

    for i in xrange(0, PopulationSize):
        tour = Tour(cities)
        shuffle(tour.tour)
        tours.append(tour)
        print str(tour.tour[0].id) + "," + str(tour.tour[1].id) + "," + str(tour.tour[2].id) + "," + str(tour.tour[3].id) + "," + str(tour.tour[4].id)
        del(tour)
    print "-"
    for j in xrange(0, PopulationSize):
        print str(tours[j].tour[0].id) + "," + str(tours[j].tour[1].id) + "," + str(tours[j].tour[2].id) + "," + str(tours[j].tour[3].id) + "," + str(tours[j].tour[4].id)

当我打印每个游览时,一切都很好。当我打印tours的内容时,每个项目都是相同的。 这是输出:

2,3,1,5,4
2,4,3,1,5
2,3,4,1,5
4,3,1,5,2
3,4,1,5,2
-
3,4,1,5,2
3,4,1,5,2
3,4,1,5,2
3,4,1,5,2
3,4,1,5,2

旅游课程:

class Tour(object):
    '''
    classdocs
    '''

    def __init__(self, cityList):
        self.tour = cityList
        self.size = len(cityList)
        self.fitness = self.getFitness(self.tour)

    def getFitness(self, tour):
        fitness = sum([self.euclideanDistance(tour[i], tour[i+1]) for i in xrange(0, self.size-1)])
        return fitness

    def euclideanDistance(self, p, q):
        distance = sqrt((p.x - q.x)**2 + (p.y - q.y)**2)
        return  distance

1 个答案:

答案 0 :(得分:3)

你几乎肯定在这里犯了两个错误之一 - 但它是你没有告诉我们的代码,所以我不知道是哪一个。

第一种可能性是你将tour存储为类属性而不是Tours中的实例属性,因此它们都共享相同的属性:

class Tour(object):
    tour = something

第二种可能性是您将城市列表复制到tour实例属性中,因此它们都具有不同的属性,但它们都是对相同列表值的引用:

class Tour(object):
    def __init__(self, cities):
        self.tour = cities

根据您更新的问题,这是第二个问题。

这最终与FAQ about multidimensional lists完全相同,除了不是直接列出列表,而是包含每个包装列表的对象列表。

无论如何,您希望每个Tour都有一个单独的列表,因此您可以使用shuffle这样的功能单独改变它们,对吗?然后,您需要在某处明确地复制列表。例如:

class Tour(object):
    def __init__(self, cities):
        self.tour = cities[:]

但是,我可能会以不同的方式写出来。首先,创建一个{em}不就地变异的shuffled方法,而是返回一个新列表:

def shuffled(iterable):
    result = list(iterable)
    shuffle(result)
    return result

然后你可以用:

替换整个第一个循环
tours = [Tour(shuffled(cities)) for _ in xrange(PopulationSize)]

虽然我们正在使用它,但您可以用以下代码替换第二个循环:

for tour in tours:
    print ','.join(city.id for city in tour)

tutorial on for loops解释了for tour in tours部分。第二行使用comprehensionjoin方法,以避免重复自己五次。