Python编写数独求解器排序时触发tuple index out of range错误
数独求解器排序逻辑IndexError问题
问题相关代码
def solver(puzzle_): puzzle_so_far = [x for x in puzzle_] unsolved = {} for row in range(9): for column in range(9): if puzzle_so_far[row][column] == 0: lot = purify(gather_square([row,column]) + puzzle_so_far[row] + [x[column] for x in puzzle_so_far]) unsolved[(row,column)]= lot unsolved = [x for x in unsolved.items()] for x in unsolved: solutions = [[y for y in range(1,10) if y not in x[1]], x[0], len(list(y for y in range(1,10) if y not in x[1]))] solutions.sort(key= lambda v : v[2]) print(solutions) if unsolved == []: return puzzle_so_far return solver(puzzle)
问题描述
我在自主实现数独求解器,清楚当前实现并非最优方案,目前仅想定位报错原因。
执行以下代码时抛出IndexError: tuple index out of range错误:
solutions.sort(key= lambda v : v[2])
我确认solutions中所有条目的第三项均为整数而非元组,条目格式示例如下:
[[3, 5, 7, 9], (0, 0), 4] [[4, 5, 7, 9], (0, 1), 4] [[2, 3, 4], (0, 4), 3] [[3, 4, 7], (0, 5), 3]
其余条目格式均与上述示例一致。访问v[0]、v[1]时提示无法对整数迭代,似乎排序逻辑是在处理元组而非完整列表,不清楚问题成因,也不知道如何正确完成列表排序。
报错原因
你对solutions的结构认知存在偏差:每次循环中你给solutions赋值的是单个待填空格的信息,是一个长度为3的一维列表,结构为[候选值列表, 坐标元组, 候选值数量],并非你预想的「存储所有待填空格信息的二维列表」。
当你对这个一维列表调用sort()方法时,排序逻辑会遍历列表内的3个元素,逐个传入lambda的参数v中:
- 第一个元素是候选值列表(如
[3,5,7,9]),访问v[2]可以取到第三个候选值,不会触发报错 - 第二个元素是长度为2的坐标元组(如
(0,0)),访问v[2]会直接触发索引越界,和你遇到的IndexError完全吻合 - 第三个元素是整数类型的候选值数量(如
4),访问v[0]/v[1]时就会抛出整数不可下标、无法迭代的错误,和你描述的现象一致
修复方案
不要在遍历单个待填空格的循环内给solutions赋值后立刻排序,需要先把所有待填空格的信息收集到同一个二维列表中,收集完成后再统一执行排序,修正后的代码片段如下:
unsolved = [x for x in unsolved.items()] solutions = [] # 先收集所有待填空格的候选信息 for x in unsolved: valid_nums = [y for y in range(1,10) if y not in x[1]] solutions.append([valid_nums, x[0], len(valid_nums)]) # 所有信息收集完成后,按候选值数量从小到大排序 solutions.sort(key=lambda v: v[2]) print(solutions)
内容的提问来源于stack exchange,提问作者Luggymaker
相关产品推荐
相关产品推荐

