这个数组赋值发生了什么?

时间:2014-09-14 17:33:50

标签: python arrays for-loop

我一直在尝试用Python制作基于终端的Minesweeper克隆。这是我产生雷区的功能:

BOMB = '#' # The symbol for the bomb
def generateField(width, height, bombs):
    field = [[0] * height] * width # Make the empty array grid
    for bomb in range(0, bombs):
        x, y = random.randint(0, width - 1), random.randint(0, height - 1)
        print((x, y)) # For debugging, remove later
        field[x][y] = BOMB #
    return field

尚未完成。 但是,当我为宽度为12,高度为12,宽度为12的炸弹的电路板调用generateField(12,12,12)时,它给出了类似这样的信息:

[
    [0, '#', 0, 0, 0, '#', '#', '#', 0, '#', '#', '#'], 
    [0, '#', 0, 0, 0, '#', '#', '#', 0, '#', '#', '#'], 
    [0, '#', 0, 0, 0, '#', '#', '#', 0, '#', '#', '#'], 
    [0, '#', 0, 0, 0, '#', '#', '#', 0, '#', '#', '#'], 
    [0, '#', 0, 0, 0, '#', '#', '#', 0, '#', '#', '#'], 
    [0, '#', 0, 0, 0, '#', '#', '#', 0, '#', '#', '#'],
    [0, '#', 0, 0, 0, '#', '#', '#', 0, '#', '#', '#'], 
    [0, '#', 0, 0, 0, '#', '#', '#', 0, '#', '#', '#'], 
    [0, '#', 0, 0, 0, '#', '#', '#', 0, '#', '#', '#'], 
    [0, '#', 0, 0, 0, '#', '#', '#', 0, '#', '#', '#'], 
    [0, '#', 0, 0, 0, '#', '#', '#', 0, '#', '#', '#'], 
    [0, '#', 0, 0, 0, '#', '#', '#', 0, '#', '#', '#']
]

有人能给我解释发生了什么,或者出了什么问题?

1 个答案:

答案 0 :(得分:2)

这部分造成了麻烦:

field = [[0] * height] * width

请改为尝试:

field = [[0] * height for _ in xrange(width)]

说明:您将相同的引用复制到列表中的单个子列表中,因此对一个元素所做的任何更改都将反映在"其他" - 因为实际上,只有一个单个子列表被多次引用。

我建议的解决方案每次都会创建不同的子列表(使用列表解析),因此不会共享子列表引用。这是Python中相当常见的问题,请查看此post以获取更多详细信息。