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

如何解决Python列表未按值传递导致井字棋AI递归计算时棋盘被修改的问题

解决井字棋AI递归中棋盘被意外修改的问题

你遇到的问题根源是浅拷贝导致的!咱们来看你的代码:当你用t = list(board)复制棋盘时,这个操作只是创建了一个新的外层列表,但里面的每一行(子列表)还是引用原board里的行对象。所以当你执行t[i][j] = letter时,其实是直接修改了原board对应行里的元素,这就导致递归过程中原棋盘被意外改动了。

解决方案:实现深拷贝

要让每个递归调用里的棋盘都是完全独立的副本,你需要对嵌套列表做深拷贝,有两种简单的方式:

方法1:手动逐行复制

用列表推导式复制每一行,这样每个子列表都是全新的对象:

import sys
def calc(board : list, turn : bool):
    game_over = True
    letter = "o" if turn else "x"
    for i in range(len(board)):
        for j in range(len(board)):
            if board[i][j] == "":
                # 手动深拷贝:复制每一行
                t = [list(row) for row in board]
                t[i][j] = letter
                game_over = False
                calc(t, not turn)
    if game_over:
        print(board)
def main():
    sys.setrecursionlimit(50000)
    board = [["", "", ""],["", "", ""],["", "", ""]]
    calc(board, True)
if __name__ == '__main__':
    main()

方法2:使用copy模块的deepcopy

如果棋盘结构更复杂(比如多层嵌套),用copy.deepcopy()会更省心,它会递归复制所有嵌套的对象:

import sys
import copy
def calc(board : list, turn : bool):
    game_over = True
    letter = "o" if turn else "x"
    for i in range(len(board)):
        for j in range(len(board)):
            if board[i][j] == "":
                # 深拷贝整个棋盘
                t = copy.deepcopy(board)
                t[i][j] = letter
                game_over = False
                calc(t, not turn)
    if game_over:
        print(board)
def main():
    sys.setrecursionlimit(50000)
    board = [["", "", ""],["", "", ""],["", "", ""]]
    calc(board, True)
if __name__ == '__main__':
    main()

为什么这样能解决问题?

不管用哪种方法,新创建的t都是一个完全独立于原board的嵌套列表,修改t的任何元素都不会影响到原棋盘,这样递归过程中每个分支的棋盘状态都是独立的,你就能正确评估所有可能的走法了。

内容的提问来源于stack exchange,提问作者Andreas Sandberg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 17:37:49