Python数独验证代码问题:valid与doubles方法失效求助
数独验证方法失效排查求助
我想制作数独并验证其有效性,目前valid和doubles方法失效,请求排查原因。流程如下:
- 创建全为
None的9×9数独 - 用
doubles方法检查行是否存在重复(存在重复返回True) - 用
valid方法检查行和列是否有效(有效返回True) print_sudoku方法用于格式化打印数独
原代码
def make_sudoku(): sudoku = [] row = [None, None, None, None, None, None, None, None, None] for i in range(9): sudoku.append(row) return sudoku def doubles(row): for e in range(len(row)): if row[e] in row: return True return False def valid(sudoku): for i in range(9): column = [] for j in range(9): column.append(sudoku[j][i]) row = sudoku[i] if (doubles(row) and doubles(column)): return False # TODO in: Check Code every 9 blocks on duplicates return True def print_sudoku(s): """ Help functie om een sudoku mooi uit te printen """ print("+-----------------+-----------------+-----------------+") for x in range(9): print("|", end="") for y in range(9): if s[x][y] is not None: print(" ", s[x][y], " ", end="") else: print(" _ ", end="") if ((y+1)%3) != 0: print(" ", end="") else: print("|", end="") print() if ((x+1)%3 == 0): print("+-----------------+-----------------+-----------------+") else: print("| | | |") if __name__ == "__main__": # Begin debugging s1 = make_sudoku() print_sudoku(s1) s1[0][0] = 5 s1[1][2] = 3 s1[7][7] = 2 s1[8][8] = 4 print_sudoku(s1) print(valid(s1)) s1[0][1] = 5 print(valid(s1))
当前输出
+-----------------+-----------------+-----------------+ | _ _ _ | _ _ _ | _ _ _ | | | | | | _ _ _ | _ _ _ | _ _ _ | | | | | | _ _ _ | _ _ _ | _ _ _ | +-----------------+-----------------+-----------------+ | _ _ _ | _ _ _ | _ _ _ | | | | | | _ _ _ | _ _ _ | _ _ _ | | | | | | _ _ _ | _ _ _ | _ _ _ | +-----------------+-----------------+-----------------+ | _ _ _ | _ _ _ | _ _ _ | | | | | | _ _ _ | _ _ _ | _ _ _ | | | | | | _ _ _ | _ _ _ | _ _ _ | +-----------------+-----------------+-----------------+ +-----------------+-----------------+-----------------+ | 5 _ 3 | _ _ _ | _ 2 4 | | | | | | 5 _ 3 | _ _ _ | _ 2 4 | | | | | | 5 _ 3 | _ _ _ | _ 2 4 | +-----------------+-----------------+-----------------+ | 5 _ 3 | _ _ _ | _ 2 4 | | | | | | 5 _ 3 | _ _ _ | _ 2 4 | | | | | | 5 _ 3 | _ _ _ | _ 2 4 | +-----------------+-----------------+-----------------+ | 5 _ 3 | _ _ _ | _ 2 4 | | | | | | 5 _ 3 | _ _ _ | _ 2 4 | | | | | | 5 _ 3 | _ _ _ | _ 2 4 | +-----------------+-----------------+-----------------+ False False
期望输出
The first sudoku + the second sudoku but than a valid one True False
问题排查与修复
1. make_sudoku方法的致命错误
你创建的数独所有行都是同一个列表对象的引用,所以修改任意一行的元素,所有行都会同步变化,这就是打印时所有行内容完全一致的原因。
修复方式:每次循环创建新的列表,而不是复用同一个row:
def make_sudoku(): sudoku = [] for i in range(9): # 每次循环生成新的行列表 sudoku.append([None]*9) return sudoku
2. doubles方法逻辑错误
当前逻辑只要元素存在于行中就返回True,但None本身会重复出现,而且没有排除元素自身的情况(比如第一个元素肯定在自己的行里)。正确逻辑应该是:统计非None元素的重复情况,如果有非None元素重复则返回True。
修复后的doubles:
def doubles(row): # 过滤掉None,只检查数字 nums = [num for num in row if num is not None] # 集合去重后长度和原列表不同,说明有重复 return len(nums) != len(set(nums))
3. valid方法逻辑错误
- 原代码用
doubles(row) and doubles(column),意思是行和列都有重复时才返回False,但实际只要行或列有重复,数独就无效,应该用or。 - 原逻辑反了:
valid方法应该在数独有效时返回True,无效时返回False。所以当doubles(row)或doubles(column)为True(存在重复),就返回False。
修复后的valid:
def valid(sudoku): for i in range(9): # 检查行 row = sudoku[i] if doubles(row): return False # 检查列 column = [sudoku[j][i] for j in range(9)] if doubles(column): return False # 后续可添加3x3区块的检查 return True
内容的提问来源于stack exchange,提问作者SiBMs
相关产品推荐
相关产品推荐

