Python - 函数更改输入列表,虽然我做了一个副本

Vad*_*der 1 python list python-2.7

我正在编写一个小的python脚本,它打印出一个行列表,其中行本身就是一个字符串列表.这就是函数的功能.它应该将列表作为输入并打印出漂亮的版本,而不实际更改列表.我可以打印出正确的输出.但仔细检查它也会改变原始列表,虽然我在函数中做的第一件事是使用这个来制作原始列表的副本grid_copy = grid[:]

问题:该脚本将任何''进入' '虽然我不修改列表

[['X', 'X', ''], ['', 'O', 'O'], ['O', 'X', '']]

成:

[X] [X] [ ]

[ ] [O] [O]

[O] [X] [ ]
Run Code Online (Sandbox Code Playgroud)

我不知道是什么原因导致列表被更改,除非我在开​​头制作副本,否则我不会在哪里引用原始列表.

我的代码包含了一些有用的注释,我添加这些注释以便更容易理解我的所作所为.如果您运行代码,我还提供了一个测试用例.

def show_grid(grid):
    """
    grid: list. A list of lines, where the lines are a list of strings
    return: None
        Prints the grid out in the classic 3x3
    """
    grid_copy = grid[:]  # make a copy so we do not want to actually change grid
    len_grid = len(grid_copy)  # I use this so much, might as well store it

    # add whitespaces to make each single spot the same width
    len_digits = len(str((len(grid_copy)**2)))  # the number of chars wide the highest number is
    # modification happens somewhere vvv
    for line in range(len_grid):
        for char in range(len_grid):
            grid_copy[line][char] = str(grid_copy[line][char]).rjust(len_digits)  # proper white spaces

    # modification happens somewhere ^^^

    # add brackets, THIS IS NOT WHERE THE PROBLEM IS
    for line in grid_copy:
        print('[' + '] ['.join(line)+']\n')  # print each symbol in a box


# TESTING TESTING
test_grid = [['X', 'X', ''], ['', 'O', 'O'], ['O', 'X', '']]
print('test_grid before: {}'.format(test_grid))
show_grid(test_grid)  # this should not modify test_grid, but it does
print('test_grid after: {}'.format(test_grid))
Run Code Online (Sandbox Code Playgroud)

OUTPUT:

test_grid before: [['X', 'X', ''], ['', 'O', 'O'], ['O', 'X', '']]
[X] [X] [ ]

[ ] [O] [O]

[O] [X] [ ]

test_grid after: [['X', 'X', ' '], [' ', 'O', 'O'], ['O', 'X', ' ']]
Run Code Online (Sandbox Code Playgroud)

hiv*_*ert 6

当您grid_copy = grid[:]在列表列表上书写时,您只复制最顶层的列表,但不复制列表本身的元素.这称为与深拷贝相对的拷贝.你应该写

grid_copy = [x[:] for x in grid]
Run Code Online (Sandbox Code Playgroud)

要么

grid_copy = copy.deepcopy(grid)
Run Code Online (Sandbox Code Playgroud)