You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何修改多维列表中一个元素会导致其他元素同步变更?

为何修改列表中的一个元素会导致其他值发生变化?

我在编写代码时遇到一个问题:修改棋盘列表中的单个元素后,其他位置的元素也同步发生了变化。相关代码及现象如下:

初始化棋盘的代码

def initial_state():
    """
    Returns starting state of the board.
    """
    base = [[None, None, None],
            [None, None, None],
            [None, None, None]]
    goof = [[None, None, None],
            [None, None, None],
            [None, None, None]]
    for i in range(3):
        for j in range(3):
            goof[i][j] = base.copy()
    return goof

执行操作的代码

def result(board, action):  
    """
    Returns the board that results from making move (i, j) on the board.
    """
    r_board = copy.deepcopy(board)
    r_action = action
    if r_board[r_action[0]][r_action[1]][r_action[2]][r_action[3]]!= None:
        raise ValueError
    else:
        turn = player(r_board)
        r_board[r_action[0]][r_action[1]][r_action[2]]= turn
    return r_board

现象

当我手动为board[0][0][0][0]赋值"X",或者通过result函数修改某个位置后,打印出的棋盘所有对应位置都变成了"X",示例输出如下:

[[[['X', None, None], [None, None, None], [None, None, None]], [['X', None, None], [None, None, None], [None, None, None]], [['X', None, None], [None, None, None], [None, None, None]]], [[['X', None, None], [None, None, None], [None, None, None]], [['X', None, None], [None, None, None], [None, None, None]], [['X', None, None], [None, None, None], [None, None, None]]], [[['X', None, None], [None, None, None], [None, None, None]], [['X', None, None], [None, None, None], [None, None, None]], [['X', None, None], [None, None, None], [None, None, None]]]]

请问为何会出现修改单个元素导致其他元素同步变更的情况?


问题根源

问题出在initial_state函数的初始化逻辑里:

  • base是一个二维列表(包含3个子列表),你使用base.copy()时,这是浅拷贝操作。浅拷贝只会复制外层列表的引用,而里面的子列表(比如[None, None, None])并不会被复制,所有goof[i][j]指向的base.copy()结果,其内部的子列表都共享同一个引用。
  • 也就是说,goof[0][0]、goof[0][1]……goof[2][2]这些位置的二维列表,它们的内部子列表都是同一个对象。当你修改其中任意一个子列表里的元素时,所有共享该引用的位置都会同步变化。

修复方法

你有两种方式解决这个问题:

方法1:使用深拷贝初始化

导入copy模块,对base进行深拷贝,确保所有层级的列表都被复制:

import copy

def initial_state():
    base = [[None, None, None],
            [None, None, None],
            [None, None, None]]
    goof = [[None, None, None],
            [None, None, None],
            [None, None, None]]
    for i in range(3):
        for j in range(3):
            goof[i][j] = copy.deepcopy(base)
    return goof

方法2:每次生成新的二维列表

不依赖拷贝,直接在循环里生成全新的二维列表,避免引用共享:

def initial_state():
    goof = [[None, None, None],
            [None, None, None],
            [None, None, None]]
    for i in range(3):
        for j in range(3):
            # 每次生成新的3x3列表
            goof[i][j] = [[None, None, None],
                          [None, None, None],
                          [None, None, None]]
    return goof

这样修改后,每个goof[i][j]都是独立的二维列表,修改其中一个元素就不会影响其他位置了。

内容的提问来源于stack exchange,提问作者Nirav Krishnakumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 22:34:53