查询网格相邻点传入负值参数触发List index out of range报错
错误原因
- 核心问题是遍历列表过程中动态删除元素导致索引错位、越界。你初始生成的相邻点列表长度固定为9,遍历用的
range(0, len(neighbors))会生成0~8的固定序列,但每次执行pop(i)都会让列表长度减1,且后续元素的索引整体前移一位。当多次删除后,列表的实际最大索引已经小于当前遍历的i值,访问neighbors[i]就会触发越界。传入负值坐标时,绝大多数相邻点都超出(0,0,50,50)的边界,会触发多次删除操作,很快就会让列表长度小于当前i值,所以直接报错;正数坐标的相邻点大多在边界内,删除操作少,刚好没触发索引超限,所以看起来运行正常。 - 次要问题是末尾固定执行
neighbors.pop(4)的逻辑不合理:如果你前面已经删除了部分元素,中心点的索引已经不再是4,甚至列表总长度不足5的时候,这行代码也会触发越界。 - 潜在隐患:从debug输出的
['-3', '2']可以看到你传入的坐标参数是字符串类型,如果没有提前转成整数,执行加减运算时会触发类型错误。
修复方案
不要在遍历原列表的时候删除元素,改为直接筛选符合条件的点存入新列表,逻辑更简洁也不会有索引问题,修复后代码如下:
def neighbors_point(self, pt, bds): # 先转换坐标为整数,避免字符串运算错误 x0, y0 = int(pt[0]), int(pt[1]) min_x, min_y, max_x, max_y = bds neighbors = [] # 遍历所有相邻偏移 for dx in (-1, 0, 1): for dy in (-1, 0, 1): # 跳过当前点本身 if dx == 0 and dy == 0: continue nx = x0 + dx ny = y0 + dy # 只保留在边界范围内的点 if min_x <= nx <= max_x and min_y <= ny <= max_y: neighbors.append((nx, ny)) return neighbors
修复后的代码完全规避了遍历删除的索引问题,也不需要硬编码删除中心点的索引,即使所有相邻点都超出边界,也只会返回空列表不会报错。
内容的提问来源于stack exchange,提问作者user10873315
相关产品推荐
相关产品推荐

