我的python列表的两个部分只有一个应该更改

时间:2018-06-13 17:05:07

标签: python list

我刚刚开始研究一个简单的遗传算法,它带有一堆点,每个点都有一系列移动指令。这些指令是一个整数列表,我将其与字典进行比较:movekey = {1:(1,1),2:(1,0),3:(1,-1),4:(0,-1),5:(-1,-1),6:(-1,0),7:(-1,1),8:(0,1)}(其中每个元组都是xy值的变化)。每个人都是一个列表列表,一个列表具有当前位置,另一个列表是其移动列表ex:[[0, 0], [4, 4, 8, 1, 7]]。然后创建一组这些个体的列表以形成群体(代码中为pop)。 创建初始种群的功能是:

def createinitpop(size):
    pop = []
    for i in range(size): pop.append([origin,[random.randint(1,8) for i in range(5)]])
    #the variable origin is preset to be [0,0]
    return pop

然后,为了将所有个体移动一步,我使用此功能:

def movedots(pop):
    for i in pop:
        print('i:',i)
        i[0][0]+= movekey[i[1][step]][0]
        # the 'step' referenced here begins at zero and counts up, i've only run it on step 0
        i[0][1] += movekey[i[1][step]][1]
        print('i:', i)
    return pop

问题在于,当我运行第二个函数时,每次迭代都会更改总体中的所有个体。 (但是我已经发现,当我将一个示例群体硬编码到movedots函数中时,它可以正常工作)。以下是两个人运行这两个函数的结果(两个人都被打印出来)

[[[0, 0], [6, 5, 2, 1, 8]], [[0, 0], [4, 7, 2, 1, 1]]]
i: [[0, 0], [6, 5, 2, 1, 8]]
i: [[-1, 0], [6, 5, 2, 1, 8]]
i: [[-1, 0], [4, 7, 2, 1, 1]]
i: [[-1, -1], [4, 7, 2, 1, 1]]
[[[-1, -1], [6, 5, 2, 1, 8]], [[-1, -1], [4, 7, 2, 1, 1]]]

理想情况下,最后一行中个人的位置应该不同,因为他们的第一个动作不同,但正如您所看到的,第三个i与第二个i相同,这表明它使用相同的值。

我不知道我是否只是不理解列表是如何工作的,或者我是否遗漏了一些愚蠢的东西。

1 个答案:

答案 0 :(得分:0)

你指出了两个对同一个地方的引用:

for i in range(size): pop.append([origin,[random.randint(1,8) for i in range(5)]])

您现在有三个相同列表的引用。当您从三个通道中的任何一个更改它时,您可以更改每个通道的数据。尝试隐式复制操作:

for i in range(size): pop.append([origin[:], ...

这将为您的每个嵌套引用提供origin的浅(一级)副本。