如何防止功能修改列表?

时间:2017-01-27 17:19:38

标签: python python-2.7

我传递给函数的列表“拼图”正在被修改,我希望该函数保持不变。

"""moveDown() works by swapping the empty space with the block above it."""
def moveDown(xPosition, yPosition, puzzle):
    returnPuzzle = list()
    returnPuzzle.append(puzzle)
    returnPuzzle = returnPuzzle[0]

    if(puzzle[yPosition][xPosition]!=0):  # is space we are moving the block into not empty?
        return -1
    if(yPosition-1<0):
        return -1

    print puzzle
    #swap
    returnPuzzle[yPosition][xPosition] = returnPuzzle[yPosition-1][xPosition]
    returnPuzzle[yPosition-1][xPosition]   = 0
    print puzzle

    return returnPuzzle

第一个print语句返回传递给该函数的原始puzzle,但第二个已修改它,好像它在returnPuzzle上而不是puzzle一样。知道为什么吗?

首次打印:[[2, 1, 3], [6, 4, 5], [8, 7, 0]]

第二次印刷:[[2, 1, 3], [6, 4, 0], [8, 7, 5]]

3 个答案:

答案 0 :(得分:2)

returnPuzzle = list()
returnPuzzle.append(puzzle)
returnPuzzle = returnPuzzle[0]

因此,您创建一个列表,为其附加一个值,然后从列表中检索该值 - 这没有任何效果,它与直接访问puzzle完全相同。要制作可以在不影响原始列表的情况下进行修改的副本,请使用:

returnPuzzle = puzzle[:]

(这是一个列表切片,使用列表开头和结尾的默认值。)

答案 1 :(得分:1)

正如其他答案所述,您只需将puzzle分配给returnPuzzle即可。因为它是一个嵌套列表,所以你需要制作一个名为&#34; deep copy&#34 ;;其他答案指的是浅拷贝,您复制列表但列表中的项目仍然相同。这意味着您最终得到一个包含相同内部列表的新外部列表。由于您正在改变内部列表,因此您也需要这些列表的副本。

最简单的方法是使用copy模块:

import copy
def moveDown(xPosition, yPosition, puzzle):
    returnPuzzle = copy.deepcopy(puzzle)

答案 2 :(得分:0)

由于puzzle是一个二维列表,因此您需要构建一个副本,以避免在复制期间保留对内部列表的引用。

def duplicate2dList(oldList):
    newList = []

    for l in oldList:
        newList.append(l[:])

    return newList