Python数独求解器代码解析:init_valid方法中self.V语句作用
Python数独求解器init_valid方法中self.V的语法与功能解析
语法解析
self.V一般是用嵌套列表推导式生成的二维集合结构,对应数独每个单元格的合法数字集合。典型实现类似这样:
self.V = [ [ set(range(1, 10)) - set(self.grid[r]) - set(self.grid[i][c] for i in range(9)) - set( self.grid[(r//3)*3 + i][(c//3)*3 + j] for i in range(3) for j in range(3) ) if self.grid[r][c] == 0 else set() for c in range(9) ] for r in range(9) ]
- 外层
for r in range(9):遍历数独的每一行 - 内层
for c in range(9):遍历当前行的每一列 - 三元表达式
if self.grid[r][c] == 0 else set():判断单元格是否为空(假设0代表未填充),已填充的单元格直接赋值空集合 - 集合差集运算:用1-9的全集,依次减去行、列、3×3宫的已存在数字,得到当前单元格的合法数字集合
功能拆解
self.V的核心作用是预计算每个单元格的合法候选数字,完全贴合数独规则:
- 全集基础:
set(range(1,10))生成数独允许的所有数字(1-9) - 排除行内重复:
set(self.grid[r])把当前行的所有数字转成集合,通过差集去掉行内已存在的数字 - 排除列内重复:
set(self.grid[i][c] for i in range(9))生成当前列的所有数字集合,差集去掉列内已存在的数字 - 排除宫内重复:
- 通过
(r//3)*3和(c//3)*3计算当前单元格所在3×3宫的起始行、列坐标 - 遍历宫的3行3列收集所有数字,转成集合后通过差集去掉宫内已存在的数字
- 通过
- 已填充单元格处理:如果单元格已有数字(非0),直接赋值空集合,因为该单元格无需再填充
解析验证思路
如果还是理解困难,可以把推导式拆成普通嵌套循环,逐行逐列拆解逻辑,更容易追踪每一步:
self.V = [] for r in range(9): current_row = [] for c in range(9): # 已填充单元格直接设为空集合 if self.grid[r][c] != 0: current_row.append(set()) continue # 提取行内已用数字 used_row = set(self.grid[r]) # 提取列内已用数字 used_col = set() for i in range(9): used_col.add(self.grid[i][c]) # 提取宫内已用数字 box_r_start = (r // 3) * 3 box_c_start = (c // 3) * 3 used_box = set() for i in range(3): for j in range(3): used_box.add(self.grid[box_r_start + i][box_c_start + j]) # 计算合法数字集合 valid_nums = set(range(1, 10)) - used_row - used_col - used_box current_row.append(valid_nums) self.V.append(current_row)
可以单独打印某一行/列的self.V值,和手动计算的合法数字对比,验证逻辑是否正确。
内容的提问来源于stack exchange,提问作者Jose Espinoza
相关产品推荐
相关产品推荐

