矩阵元素查找时遇TypeError: NoneType不可下标访问问题求助
问题修复:矩阵元素查找时的NoneType下标错误
问题场景
尝试在NumPy矩阵中查找指定元素的行列索引并存入两个元组,运行时触发错误:
TypeError: 'NoneType' object is not subscriptable
报错行:theLine = theTuple[0]
原代码如下:
from typing import NewType import numpy as np def find(element:int, matrix:np.array) ->tuple: '''Returnez un tuplu cu indicii elementului cautat''' myTuple = tuple() for i in range(2): for j in range(3): if matrix[i][j] == element: myTuple += (i,) myTuple += (j,) return myTuple def pos_values(matrix: np.array, a: int, b: int, c: int, d: int) -> tuple: rows = tuple() cols = tuple() for myElement in range (a, b): theTuple = find(myElement, matrix) theLine = theTuple[0] theColumn = theTuple[1] rows += (theLine, ) cols += (theColumn, ) return rows,cols mat = np.arange(12).reshape(3, 4) rows, cols = pos_values(mat, 2, 4, 6, 8) assert np.all(rows == [0, 0, 1, 1, 1, 2]) assert np.all(cols == [2, 3, 0, 2, 3, 0]) mat = -np.arange(12).reshape(3, 4) rows, cols = pos_values(mat, 2, 4, 6, 8) assert np.all(rows == []) assert np.all(cols == [])
错误原因
- find函数遍历范围错误:循环只遍历了前2行(
range(2))和前3列(range(3)),但测试用矩阵是3行4列,导致大部分元素无法被找到,此时find函数无返回值,默认返回None。 - 未处理元素不存在的情况:pos_values函数直接对
theTuple取下标,当元素不存在时theTuple是None,触发下标错误。 - pos_values函数逻辑缺失:只处理了
range(a,b)的元素,完全没处理range(c,d)的元素,不符合断言中需要包含6-8元素的要求。
修复方案
1. 修正find函数的遍历范围
遍历矩阵所有行和列,未找到元素时返回空元组:
def find(element:int, matrix:np.array) -> tuple: '''返回找到的元素的行列索引元组,未找到则返回空元组''' for i in range(matrix.shape[0]): for j in range(matrix.shape[1]): if matrix[i][j] == element: return (i, j) return ()
2. 完善pos_values函数的逻辑
- 同时处理
a到b和c到d的元素范围 - 判断find函数的返回值,跳过不存在的元素
- 先用列表暂存数据(比元组拼接效率更高),最后转成元组
修正后的pos_values函数:
def pos_values(matrix: np.array, a: int, b: int, c: int, d: int) -> tuple: rows = [] cols = [] # 处理a到b区间的元素 for myElement in range(a, b): pos = find(myElement, matrix) if pos: rows.append(pos[0]) cols.append(pos[1]) # 处理c到d区间的元素 for myElement in range(c, d): pos = find(myElement, matrix) if pos: rows.append(pos[0]) cols.append(pos[1]) return tuple(rows), tuple(cols)
完整修复后代码
import numpy as np def find(element:int, matrix:np.array) -> tuple: '''返回找到的元素的行列索引元组,未找到则返回空元组''' for i in range(matrix.shape[0]): for j in range(matrix.shape[1]): if matrix[i][j] == element: return (i, j) return () def pos_values(matrix: np.array, a: int, b: int, c: int, d: int) -> tuple: rows = [] cols = [] # 处理a到b区间的元素 for myElement in range(a, b): pos = find(myElement, matrix) if pos: rows.append(pos[0]) cols.append(pos[1]) # 处理c到d区间的元素 for myElement in range(c, d): pos = find(myElement, matrix) if pos: rows.append(pos[0]) cols.append(pos[1]) return tuple(rows), tuple(cols) # 测试用例1 mat = np.arange(12).reshape(3, 4) rows, cols = pos_values(mat, 2, 4, 6, 8) assert np.all(rows == [0, 0, 1, 1, 1, 2]) assert np.all(cols == [2, 3, 0, 2, 3, 0]) # 测试用例2 mat = -np.arange(12).reshape(3, 4) rows, cols = pos_values(mat, 2, 4, 6, 8) assert np.all(rows == []) assert np.all(cols == [])
额外优化(可选)
利用NumPy内置函数可更高效查找元素,避免手动循环:
def find(element:int, matrix:np.array) -> tuple: indices = np.where(matrix == element) if len(indices[0]) > 0: return (indices[0][0], indices[1][0]) return ()
内容的提问来源于stack exchange,提问作者Lucian Schipor
相关产品推荐
相关产品推荐

