元素的值与附加到列表的值不同

时间:2018-07-23 11:22:14

标签: python python-3.x

这是我代码的一部分。当我执行程序时,我得到的输出将包含在代码下方。

    currentPos = playerPosition
    modifiedCords = freespaceCords
    pathList = []
    while(True):
        adjacentList = []
        potentialMoveList = []

        currentPos[0] = currentPos[0] - 1
        adjacentList.append(currentPos)
        print(currentPos)

        currentPos[0] = currentPos[0] + 2
        adjacentList.append(currentPos)
        print(currentPos)

        currentPos[0] = currentPos[0] - 1
        currentPos[1] = currentPos[1] - 1
        adjacentList.append(currentPos)
        print(currentPos)

        currentPos[1] = currentPos[1] + 2
        adjacentList.append(currentPos)
        print(currentPos)
        currentPos[1] = currentPos[1] - 1

        print("")
        print(adjacentList)
        print("")

输出:

[0, 1]

[2, 1]

[1, 0]

[1, 2]


[[1, 1], [1, 1], [1, 1], [1, 1]]

我希望4个元素的列表包含前四个单独打印的元素,例如:

[ [0,1] , [2,1] , [1,0] , [1,2] ]

请有人为我的问题提供解决方案,解释为什么他们的解决方案有效,为什么我的代码无效。

谢谢。

4 个答案:

答案 0 :(得分:1)

这样做的时候

adjacentList.append(currentPos)

您要将引用currentPos附加到adjacentList。因此,每次更改currentPos时,实际上实际上也在更改adjacentList中的元素。如果在中间步骤中打印adjacentList,您将会明白我的意思。

要避免这种情况,您可以添加列表的副本:

adjacentList.append(list(currentPos))

这里是一个示例,您可以在其中看到我的描述:

>>> l = [1, 1]
>>> adjacentList = []
>>> adjacentList.append(l)
>>> adjacentList
[[1, 1]]
>>> l[1] = 2
>>> adjacentList
[[1, 2]]

答案 1 :(得分:1)

您要添加参考,而不是列表的副本。 为了表明我们可以使用内置的id函数

将以下代码添加到循环的结尾

print(id(adjacentList[0])
print(id(adjacentList[1])
print(id(adjacentList[2])
print(id(adjacentList[3])
print(id(currentPos))

您会发现adjacentListcurrentPos中的四个元素具有相同的ID,这与内存中的对象完全相同。

使用许多方法之一(而不是只引用currentPos的副本而不引用)(我只会提及其中一种,而其他方法可以选中here

# Since Python 3.3
adjacentList.append(currentPos.copy())

答案 2 :(得分:0)

.append(currentPosition)添加到列表时,您将同一实际对象添加4次。由于该对象在4个位置中,因此如果更改它,则所有位置都会更改。最简单的方法是存储对象的副本,只需添加.append(list(currentPosition)).append(currentPosition[:])即可完成。

答案 3 :(得分:0)

您的问题已被其他人回答。无论如何,我想通过一个非常简单的示例来补充上述答案,以帮助您更好地理解。

执行以下代码,

input = [1,2]
output = []

output.append(input)
print("output list after appending %s"%output)

input[0] = 4
output.append(input)
print("output list after appending again %s"%output)

您将获得以下输出

output list after appending [[1, 2]]
output list after appending again [[4, 2], [4, 2]]

可以看出,在第二次追加之后,甚至output [0]也被重写。这是因为output [0]引用了input [],并且在修改输入列表时,即使output [0]也会获得最新值。

另一方面,如果您执行以下操作,

input = [1,2]
output = []

output.append(input.copy())
print("output list after appending %s"%output)

input[0] = 4
output.append(input.copy())
print("output list after appending again %s"%output)

您将获得预期的输出

output list after appending [[1, 2]]
output list after appending again [[1, 2], [4, 2]]

现在输出[0]不会被覆盖,因为它是输入[]的副本,而不是引用。