python matrices - 列表索引超出范围

时间:2012-12-08 22:20:34

标签: python list matrix range out

嘿我正在写一个函数,它接受一个矩阵输入,如下面的那个,并返回它的逆,其中所有的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

5 个答案:

答案 0 :(得分:1)

这并没有直接回答你的问题,但我想指出,在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)]

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

答案 1 :(得分:0)

while (graph[r][c] == 0 or graph[r][c] == 1): # while the current row has a value.

在将-possible-值与0或1进行比较之前,首先必须确保两个索引都存在。这会导致异常。要反转矩阵,您可能需要执行类似

的操作
for row in graph:
    for idx, v in enumerate (row):
        row [idx] = 0 if v else 1

答案 2 :(得分:0)

错误在于你的“当前行有一个值”。当您遍历行中的元素时,这将始终为真,当您到达它们时,您将获得异常。

相反,请使用:

for r in range(len(graph):
    for c in range(len(graph[0]):
        # do something with graph[r][c]

答案 3 :(得分:0)

这很简单。 基本上你需要找到数组中元素的数量

 mylist = [1,2,3,4,5]
 len(mylist) # returns 5
 #this gives the number of elements.
 rows=len(g1) # get the number of rows
 columns=len(g1[0]) #get the number of columns
 #Now iterate over the number of rows and columns
 for r in range(0, rows):
    for c in range (0,columns):
       if (r==c):
              g1[r][c]=0
       else:
           g1[r][c]=1-g1[r][c]

希望有所帮助

答案 4 :(得分:0)

不是您问题的答案,但这是一种“简单”的方法

return [[0 if i2==i else 1 if item == 0 else 0 for i2,item in enumerate(row)] for i,row in graph]