2

ねえ、私は次のような行列入力を受け取り、その逆を返す関数を書いています。ここでは、左上から右下の0の対角線を維持しながら、すべての1が0に変更され、すべての0が1に変更されます。



入力例:

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
4

5 に答える 5

1


    for <element> in <container>:
これはあなたの質問に直接答えるものではありませんが、Pythonではステートメントを使用することでインデックスを使用する必要性を減らすことができ、場合によってはなくすことができることを指摘したいと思います。組み込み関数と併用することで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]]

これはより単純で、明らかに機能します。もう1つのポイントは、関数を変更可能な(変更可能な)コンテナーであるリストのリストに適用しているため、コンテナーがインプレースで変更されているため、コンテナーを返す必要がないことです。関数を使いやすくするので間違いではありませんが、気づかなかったかもしれません。

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)]

それらが機能する方法のために、このバージョンはその場でグラフを変更しませんが、代わりに新しいグラフを作成して返します。

于 2012-12-08T22:53:43.033 に答える
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
于 2012-12-08T22:25:58.527 に答える
0

間違いは「現在の行に値がある間」にあります。これは、行の要素を反復処理する間は常に当てはまり、それらを超えて到達すると、例外が発生します。

代わりに、以下を使用してください。

for r in range(len(graph):
    for c in range(len(graph[0]):
        # do something with graph[r][c]
于 2012-12-08T22:26:27.917 に答える
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]

お役に立てば幸い

于 2012-12-08T22:28:13.580 に答える
0

あなたの質問への答えではありませんが、ここにそれを行うための「簡単な」方法があります

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

于 2012-12-08T22:30:33.487 に答える