Python递归深度超限:数独求解无法输出结果求助
问题根源分析与修复方案
你的代码存在变量名冲突和逻辑判断错误,和IDE(VSCode/PyCharm)无关,也与递归栈大小没有关系,以下是具体问题和修复步骤:
1. 核心问题:变量名重复覆盖
多个函数里用了重复的变量名(比如x),直接覆盖了传入的参数值,导致逻辑彻底混乱:
solve函数中,已经从find_empty拿到空位置的(y, x),但后续循环又用for x in range(1,10),直接覆盖了空位置的列坐标x,导致后续操作全错。valid函数中,参数是(board, y, x)(行、列),但检查行/列时循环变量又用x,完全覆盖了参数里的坐标值,判断逻辑直接失效。
2. 次要问题:逻辑判断条件错误
valid函数里的判断条件完全错误,比如board[y][x] == x,这里的x是循环变量,不是要验证的数值;还有(y != x)这种无意义的坐标判断,应该是排除当前检查的单元格本身。find_empty函数里遍历行和列的逻辑搞反了,board[y][x] ==0应该是board[x][y] ==0,返回的坐标顺序也对应错误。
修复后的完整代码
board = [ [7, 8, 0, 4, 0, 0, 1, 2, 0], [6, 0, 0, 0, 7, 5, 0, 0, 9], [0, 0, 0, 6, 0, 1, 0, 7, 8], [0, 0, 7, 0, 4, 0, 2, 6, 0], [0, 0, 1, 0, 5, 0, 9, 3, 0], [9, 0, 4, 0, 6, 0, 0, 0, 5], [0, 7, 0, 3, 0, 0, 0, 1, 2], [1, 2, 0, 0, 0, 7, 4, 0, 0], [0, 4, 9, 2, 0, 6, 0, 0, 7] ] def solve(board): find = find_empty(board) if not find: return True else: row, col = find # 用清晰的变量名避免冲突 for num in range(1, 10): # 用num代替x,避免覆盖坐标变量 if valid(board, num, row, col): board[row][col] = num if solve(board): return True board[row][col] = 0 return False def valid(board, num, row, col): # 检查当前行 for i in range(len(board[0])): if board[row][i] == num and col != i: return False # 检查当前列 for i in range(len(board)): if board[i][col] == num and row != i: return False # 检查3x3小方格 box_row = row // 3 box_col = col // 3 for i in range(box_row * 3, box_row * 3 + 3): for j in range(box_col * 3, box_col * 3 + 3): if board[i][j] == num and (i, j) != (row, col): return False return True def print_board(board): for i in range(len(board)): if i % 3 == 0 and i != 0: print("- - - - - - - - - - - - ") for j in range(len(board[0])): if j % 3 == 0 and j != 0: print(" | ", end="") if j == 8: print(board[i][j]) else: print(str(board[i][j]) + " ", end="") def find_empty(board): for i in range(len(board)): for j in range(len(board[0])): if board[i][j] == 0: return (i, j) # 返回(行, 列)的正确顺序 return None print_board(board) solve(board) print("\n" + "_"*20) print_board(board)
关键修复点说明
- 替换容易冲突的变量名:用
row/col代替y/x,用num表示要尝试填入的数字,用i/j作为循环变量,彻底避免变量覆盖。 - 调整
valid函数参数顺序,把要验证的数字num放在前面,避免和坐标变量混淆。 - 修正
find_empty的遍历逻辑,确保正确找到空单元格的行和列。 - 修复
valid函数的判断条件,正确排除当前单元格本身,同时对比要填入的数字num而非循环变量。
运行修复后的代码即可正常输出求解后的数独棋盘,IDE差异不会影响代码运行结果。
内容的提问来源于stack exchange,提问作者Colby Canselo
相关产品推荐
相关产品推荐

