Python中numpy.ndarray转set报错及网格三连数组合查找求助
问题解决:3×3网格中找出未出现在输入序列的三连组合
需求说明
输入数字序列,在3×3的1-9网格中找出所有未出现在输入序列中的三连数组合(包含行、列、对角线)。例如输入序列'372003',预期输出为[1, 5, 9]和[4, 5, 6]。
原代码报错原因
原代码运行抛出TypeError: unhashable type: 'numpy.ndarray',核心问题是:
arr.take()返回的elements是二维numpy数组(比如取行时得到array([[1,2,3]])),直接转集合时,集合会尝试将子数组作为元素,但numpy数组属于不可哈希类型,导致报错。- 此外原代码的
axis遍历逻辑无法正确提取对角线,存在逻辑漏洞。
修正方案
- 提取行/列/对角线元素后,先扁平化转为一维数组,再转换为集合进行判断
- 拆分行、列、对角线的处理逻辑,避免用复杂的
take参数导致逻辑混乱 - 过滤输入序列中的0(网格仅包含1-9,0不属于目标范围)
修正后的代码
import numpy as np # 定义3×3的1-9网格 grid = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # 输入数字序列 seq = '372003' # 转换为数字集合,过滤掉无关的0 seq_set = set(int(d) for d in seq if d != '0') # 存储符合条件的三连组合 result = [] # 处理所有行 for row in grid: row_elements = set(row) if row_elements.isdisjoint(seq_set): result.append(row.tolist()) # 处理所有列(转置网格后遍历行即为原网格的列) for col in grid.T: col_elements = set(col) if col_elements.isdisjoint(seq_set): result.append(col.tolist()) # 处理主对角线(左上到右下) main_diag = grid.diagonal() if set(main_diag).isdisjoint(seq_set): result.append(main_diag.tolist()) # 处理副对角线(右上到左下) anti_diag = np.fliplr(grid).diagonal() if set(anti_diag).isdisjoint(seq_set): result.append(anti_diag.tolist()) # 输出结果 for combo in result: print(combo)
算法可行性验证
- 输入处理:过滤序列中的0,避免无效值干扰判断逻辑
- 元素提取:直接遍历行、转置后的列,用
diagonal()和fliplr()提取对角线,逻辑清晰且准确率高 - 判断逻辑:用
isdisjoint()判断集合是否无交集,等价于“三连数中没有任何一个出现在输入序列”,完全符合需求
运行修正后的代码,输入'372003'时,输出为[4, 5, 6]和[1, 5, 9],与预期结果一致。
内容的提问来源于stack exchange,提问作者roee
相关产品推荐
相关产品推荐

