Skip to main content
 首页 » 编程设计

python 矩阵之列表索引超出范围

2025年05月04日6jiqing9006

嘿,我正在编写一个函数,它接受一个矩阵输入(如下所示)并返回其逆矩阵,其中所有 1 都变为 0,所有 0 变为 1,同时保持对角线从左上角到右下角0秒。



输入示例:

g1 = [[0, 1, 1, 0], 
     [1, 0, 0, 1], 
     [1, 0, 0, 1], 
     [0, 1, 1, 0]] 



该函数应输出如下:

g1 = [[0, 0, 0, 1], 
     [0, 0, 1, 0], 
     [0, 1, 0, 0], 
     [1, 0, 0, 0]] 



当我运行该程序时,它会抛出“列表索引超出范围”错误。我确定这是因为我设置的循环试图访问不存在的值,但我如何允许输入未知的行和列大小?我只知道如何使用单个列表来执行此操作,但是列表列表?这是函数,不包括调用它的测试函数:

def inverse_graph(graph): 
    # take in graph 
    # change all zeros to ones and ones to zeros 
 
    r, c = 0, 0 # row, column equal zero 
 
    while (graph[r][c] == 0 or graph[r][c] == 1): # while the current row has a value. 
        while (graph[r][c] == 0 or graph[r][c] == 1): # while the current column has a value 
            if (graph[r][c] == 0): 
                graph[r][c] = 1 
            elif (graph[r][c] == 1): 
                graph[r][c] = 0 
            c+=1 
        c=0 
        r+=1 
 
    c=0 
    r=0 
 
    # sets diagonal to zeros 
 
    while (g1[r][c] == 0 or g1[r][c] == 1): 
        g1[r][c]=0 
        c+=1 
        r+=1 
 
    return graph 

请您参考如下方法:

这并没有直接回答您的问题,但我想指出,在 Python 中,您通常可以通过使用
来减少甚至有时消除使用索引的需要 for <element> in <container>:
陈述。通过将它与内置的 enumerate() 一起使用函数,可以同时获取索引和对应的元素
for <index>,<element> in enumerate(<container>):

将它们应用于您的问题将允许这样的事情:

g1 = [[0, 1, 1, 0], 
      [1, 0, 0, 1], 
      [1, 0, 0, 1], 
      [0, 1, 1, 0]] 
 
def inverse_graph(graph): 
    """ invert zeroes and ones in a square graph 
        but force diagonal elements to be zero 
    """ 
    for i,row in enumerate(graph): 
        for j,cell in enumerate(row): 
            row[j] = 0 if cell or i == j else 1 
    return graph 
 
print(g1) 
print(inverse_graph(g1)) 

输出:

[[0, 1, 1, 0], [1, 0, 0, 1], [1, 0, 0, 1], [0, 1, 1, 0]] 
[[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]] 

哪个更简单并且显然有效。另一点是,由于您将函数应用于可变(可更改)容器,一个列表列表,因此实际上没有必要返回容器,因为它正在就地更改。这样做并没有错,因为它可以使功能的使用更容易,但这是您可能没有意识到的。

您可以通过使用一个叫做 list comprehension 的东西来进一步缩短函数并完全消除索引。 :

def inverse_graph(graph): 
    return [[0 if cell or i == j else 1 
                for j,cell in enumerate(row)] 
                    for i,row in enumerate(graph)] 

由于它们的工作方式,此版本不会就地更改图表,而是创建并返回一个新图表。