def list_2d_locations(rows, columns, low_range, high_range):
matrix = list_2d_generate(rows, columns, low_range, high_range)
print(matrix)
low_val = high_val = matrix[0][0]
for i in range(rows):
for j in range(columns):
if matrix[i][j] < low_val:
low_val = matrix[i][j]
low_loc = [i][j]
if matrix[i][j] > high_val:
high_val = matrix[i][j]
high_loc = [i][j]
return low_val, high_val, low_loc, high_loc
我这里有一个函数,它应该在列表列表(即矩阵)中找到最小和最大的数字,并返回实际值,以及该值在矩阵内的位置。现在我的问题是high_loc = [i][j]
和low_loc = [i][j]
都给了我“列表索引超出范围”的错误,我不明白为什么。 if语句也不会超出范围,然后是相同的逻辑吗?
答案 0 :(得分:1)
这是一个解决方案。它是干净的。但是,对于大型矩阵,它应该被优化为仅对它们进行一次迭代并在该迭代期间收集所有信息。
m = [[3,5,1], [56,43,12], [4,52,673]]
def f(matrix):
cols = len(matrix[0])
flatten = [val for row in matrix for val in row]
min_val, max_val = min(flatten), max(flatten)
min_i, max_i = flatten.index(min_val), flatten.index(max_val)
return min_val, max_val, divmod(min_i, cols), divmod(max_i, cols)
>>> f(m)
(1, 673, (0, 2), (2, 2))
编辑:您知道吗,这是优化版本:
def f(matrix):
try:
min_val, max_val = matrix[0][0], matrix[0][0]
except IndexError:
raise ValueError("Expected a real matrix.") from None
genexp = (val for row in matrix for val in row)
cols = len(matrix[0])
min_i, max_i = (0, 0), (0, 0)
for i, val in enumerate(genexp):
if val < min_val:
min_val, min_i = val, divmod(i, cols)
elif val > max_val:
max_val, max_i = val, divmod(i, cols)
return min_val, max_val, min_i, max_i
EDIT2:
这是一种更好理解的体验,可以由您完成。如果您想了解代码,我建议您也这样做。
>>> matrix = [[3,5,1], [56,43,12], [4,52,673]]
>>> flatten = [val for row in matrix for val in row]
>>> flatten
[3, 5, 1, 56, 43, 12, 4, 52, 673]
>>> flatten.index(56)
3
>>> divmod(3,3)
(1, 0)
>>> for elem in enumerate(["one", "two", "three"]):
... elem
...
(0, 'one')
(1, 'two')
(2, 'three')
答案 1 :(得分:1)
问题在于low_loc = [i][j]
行。在=
符号右侧的表达式中,[i]
是包含单个元素的列表,[i][j]
表示尝试在位置{{1}处提取元素从该列表中。除非j
,否则将失败。也许你想要j == 0
或low_loc = [i, j]
? (当然,同样的评论也适用于low_loc = (i, j)
行。)