Python代码出现KeyError排查求助:已测试判断条件仍未解决
解决Python代码中的KeyError异常问题
运行Python代码时持续遇到KeyError异常,已尝试打印if判断语句两侧的内容测试,但问题仍未解决。代码需要比较两处对应值,若相等则继续执行程序。确认代码中'code'标签在两处均存在,且对应的都是包含4个整数的数组(示例:[100,100,100,100]、[0,1,0,1])。
相关代码
def colapse(): queue = [] colapsed = random.choice(idMinEntrepy(board)) check = random.choice(range(len(board[colapsed[0]][colapsed[1]]))) board[colapsed[0]][colapsed[1]] = board[colapsed[0]][colapsed[1]][check] queue.append(colapsed) while len(queue)>0: for pos in ((1,0),(0,1),(-1,0),(0,-1)): valids = [] if -1 < queue[0][0]+pos[0] < domain[1] and -1 < queue[0][1]+pos[1] < domain[0]: #here are my tested that did not result in the "KeyError" #print(board[queue[0][0]][queue[0][1]][check].get("code")[yxtosideindex(pos[0],pos[1])]) #print(board[queue[0][0]+pos[0]][queue[0][1]+pos[1]][check].get("code")[yxtosideindex(pos[0], pos[1])]) # here's the issue / / / if board[queue[0][0]][queue[0][1]][check].get("code")[yxtosideindex(pos[0],pos[1])] == board[queue[0][0]+pos[0]][queue[0][1]+pos[1]][check].get("code")[yxtosideindex(pos[0],pos[1])]: valids.append(board[queue[0][0]+pos[0]][queue[0][1]+pos[1]]) queue.append((queue[0][0]+pos[0],queue[0][1]+pos[1])) board[queue[0][0]][queue[0][1]] = valids queue.pop(0)
问题分析与解决
1. 核心KeyError原因
代码开头执行board[colapsed[0]][colapsed[1]] = board[colapsed[0]][colapsed[1]][check]后,该位置的board元素从包含多个字典的列表被替换成了单个字典。但后续while循环中,你仍然用board[queue[0][0]][queue[0][1]][check]访问这个位置——此时这里是单个字典,用数字check作为索引去访问字典的键,而字典中不存在名为check的键,直接触发KeyError。
2. 其他逻辑问题
valids在for循环内部初始化,每次循环都会被清空,最终board[queue[0][0]][queue[0][1]] = valids只会保留最后一次循环的结果(大概率为空)。queue.append(...)放在for循环外部,此时pos是最后一次循环的坐标(如(-1,0)),不符合遍历四个方向的逻辑。- 直接将
valids赋值给当前位置的board元素,会破坏原有的数据结构,导致后续循环访问时出现更多错误。
3. 修正后的代码示例
import random def colapse(): queue = [] colapsed = random.choice(idMinEntrepy(board)) # 保存当前单元格的所有可选选项 cell_options = board[colapsed[0]][colapsed[1]] check = random.choice(range(len(cell_options))) # 坍缩为选中的单个选项 collapsed_cell = cell_options[check] board[colapsed[0]][colapsed[1]] = collapsed_cell queue.append(colapsed) while queue: current_pos = queue.pop(0) # 遍历四个相邻方向 for pos in ((1,0),(0,1),(-1,0),(0,-1)): x = current_pos[0] + pos[0] y = current_pos[1] + pos[1] # 检查坐标是否在有效范围内(避免负数索引) if 0 <= x < domain[1] and 0 <= y < domain[0]: # 获取当前坍缩单元格对应方向的code值 current_code = collapsed_cell.get("code")[yxtosideindex(pos[0], pos[1])] neighbor_cell = board[x][y] # 仅处理未坍缩的单元格(仍为列表) if isinstance(neighbor_cell, list): valid_options = [] # 筛选相邻单元格中code匹配的选项 for option in neighbor_cell: neighbor_code = option.get("code")[yxtosideindex(pos[0], pos[1])] if current_code == neighbor_code: valid_options.append(option) # 更新相邻单元格的有效选项 board[x][y] = valid_options # 若有有效选项且未在队列中,加入队列继续处理 if valid_options and (x, y) not in queue: queue.append((x, y))
修正说明
- 保存坍缩后的单元格为变量
collapsed_cell,后续直接使用该变量访问code,避免重复索引错误。 - 提前取出
queue[0]并pop(0),明确当前处理的坐标,减少逻辑混淆。 - 调整逻辑为筛选相邻单元格的有效选项,符合类似Wave Function Collapse算法的坍缩逻辑。
- 增加
isinstance判断,避免对已坍缩的单个字典进行无效遍历。 - 修正坐标范围判断,避免负数索引导致的访问错误。
内容的提问来源于stack exchange,提问作者ReesesBeans
相关产品推荐
相关产品推荐

