0
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 语句是否也超出了同样的逻辑范围?

4

2 回答 2

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

编辑2:

以下是您可以更好地理解的经验。如果您想理解代码,我建议您也这样做。

>>> 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')
于 2013-11-14T07:48:23.783 回答
1

问题出在线路上low_loc = [i][j]=在符号右侧的表达式中,[i]是一个具有单个元素的列表,[i][j]表示尝试j从该列表中提取位置处的元素。除非j == 0. 也许你想要low_loc = [i, j]或者low_loc = (i, j)相反?(当然,同样的注释也适用于 line high_loc = [i][j]。)

于 2013-11-14T08:02:47.020 回答