为何索引NumPy整数数组时会触发‘bool对象不可下标’错误?
错误成因分析
看你标注$$$$的代码行:
conn_comp.onborder = irow == 0 or irow == nrows - 1 or icol == 0 or icol == ncols - 1
在ConnectedComponents类的初始化方法里,self.onborder被定义为NumPy二维int数组,用来记录每个单元格是否处于网格边界。但上面这行代码直接把整个数组覆盖成了单个布尔值(True/False)。
当后续执行到标注<<<<===========的代码时:
self.onborder[comp1] += self.onborder[comp2]
此时self.onborder已经变成了布尔值,而布尔值不支持下标访问([]操作),因此触发TypeError: 'bool' object is not subscriptable。
修复方案
1. 修正边界标记赋值逻辑
把标注$$$$的代码改成给数组对应位置赋值,而非覆盖整个数组:
conn_comp.onborder[irow, icol] = irow == 0 or irow == nrows - 1 or icol == 0 or icol == ncols - 1
这样就能正确设置每个0单元格的边界状态,保留onborder的数组类型。
2. 优化连通分量合并时的边界标记逻辑
原代码用加法合并边界标记不合理——我们只需要判断组件中是否存在边界单元格,而非统计数量。把union中的边界合并代码替换为:
self.onborder[comp1] = max(self.onborder[comp1], self.onborder[comp2])
(利用int类型特性,1代表是边界,0代表不是,取最大值即可判断组件是否触达边界)
修复后完整代码
import numpy as np # "岛屿"是4连通的0单元格区域,"封闭岛屿"指完全被1包围的岛屿,"开放岛屿"指至少有一个单元格邻接网格边界的岛屿,单元格用二元组(row,col)索引 class Solution: def closedIsland(self, grid: list[list[int]]) -> int: nrows = len(grid) ncols = len(grid[0]) conn_comp = self.ConnectedComponents(nrows, ncols) # 收集0单元格的连通分量 for irow in range(nrows): for icol in range(ncols): if grid[irow][icol] == 1: continue # 修复:给对应位置赋值,而非覆盖整个数组 conn_comp.onborder[irow, icol] = irow == 0 or irow == nrows - 1 or icol == 0 or icol == ncols - 1 # 检查上方单元格 if irow > 0 and grid[irow - 1][icol] == 0: conn_comp.union((irow, icol), (irow - 1, icol)) # 检查左侧单元格 if icol > 0 and grid[irow][icol - 1] == 0: conn_comp.union((irow, icol), (irow, icol - 1)) # 统计封闭岛屿数量:遍历所有连通分量根节点,根节点边界标记为0的分量即为封闭岛屿 visited_roots = set() closed_count = 0 for irow in range(nrows): for icol in range(ncols): if grid[irow][icol] == 1: continue root = conn_comp.find((irow, icol)) if root not in visited_roots: visited_roots.add(root) if conn_comp.onborder[root] == 0: closed_count += 1 return closed_count class ConnectedComponents: def __init__(self, nrows, ncols): self.parent = np.zeros((nrows, ncols), dtype=object) for row in range(nrows): for col in range(ncols): self.parent[row, col] = (row, col) self.size = np.zeros((nrows, ncols), dtype=int) self.onborder = np.zeros((nrows, ncols), dtype=int) def find(self, rowcol): # 路径压缩优化,提升查找效率 if rowcol != self.parent[rowcol]: self.parent[rowcol] = self.find(self.parent[rowcol]) return self.parent[rowcol] def union(self, rowcol_1, rowcol_2): comp1 = self.find(rowcol_1) comp2 = self.find(rowcol_2) if comp1 == comp2: return if self.size[comp1] >= self.size[comp2]: self.parent[comp2] = comp1 self.size[comp1] += self.size[comp2] # 修复:用max判断组件是否触达边界 self.onborder[comp1] = max(self.onborder[comp1], self.onborder[comp2]) else: self.parent[comp1] = comp2 self.size[comp2] += self.size[comp1] self.onborder[comp2] = max(self.onborder[comp2], self.onborder[comp1]) grid = [[1,1,1,1,1,1,1,0],[1,0,0,0,0,1,1,0],[1,0,1,0,1,1,1,0],[1,0,0,0,0,1,0,1],[1,1,1,1,1,1,1,0]] print("result", Solution().closedIsland(grid)) # 输出应为2
额外说明
- 给
find方法添加了路径压缩优化,提升连通分量查找效率。 - 补充了统计封闭岛屿的逻辑,让程序实现完整功能。
内容的提问来源于stack exchange,提问作者Mark Lavin
相关产品推荐
相关产品推荐

