首页 > 解决方案 > 2048 游戏列表比较

问题描述

def helper(mat):
    for row in mat:
        zero_list = []
        for subrow in row:
            if subrow == 0:
                row.remove(0)
                zero_list.append(0)
        row.extend(zero_list)
    return mat


def merge_left(mat):
    result = mat.copy()
    helper(mat)
    counter = 0 
    for i in range(len(mat)):
        current_tile = 0
        for j in range(len(mat)):
            if mat[i][j] == current_tile:
                mat[i][j-1] *= 2
                mat[i][j] = 0
                counter += mat[i][j-1]
            current_tile = mat[i][j]
    helper(mat)
    return result == mat

print(merge_left([[2, 2, 0, 2], [4, 0, 0, 0], [4, 8, 0, 4], [0, 0, 0, 2]]))

大家好,

我在上面的代码中得到的 merge_left 结果对于测试用例是 True 。鉴于该结果是 mat 的副本。如何通过此代码以类似于 mat 的方式更改结果?如果我写了,我会理解这种情况

result = mat instead of result = mat.copy()

为什么会这样?我的目标是比较输入垫的两种状态。在代码更改垫子之前和之后。

标签: listfunctioncomparisonmutable

解决方案


list.copy()只克隆外部列表。内部列表仍然是别名,因此修改其中一个会修改resultand mat。这是问题的最小再现:

>>> x = [[1, 2]]
>>> y = x.copy()
>>> y[0][0] += 1
>>> y
[[2, 2]]
>>> x
[[2, 2]]

您可以使用[row[:] for row in mat]深度复制矩阵中的每一行。切片和copy几乎相同。

您也可以使用copy.deepcopy,但这样做太过分了。

此外,row.remove(0)在迭代 时row,就像在添加或删除元素时迭代任何列表一样,很可能是一个错误。for subrow in row[:]:至少考虑重新设计或使用。


推荐阅读