You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何索引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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 00:11:11