65211


AOJの[ITP1_7_C問題](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_7_C&lang=ja)からのものです  
H行W列の行列が与えられ、その行ごとの和と列ごとの和をH+1行、W+1行目に追加した後に  
出力するコードを書くのが目標です。((H+1,W+1)の場所には全要素の総和を出力)

pythonのH+1行W+1列の2次元リスト(行列)を0で埋めた後(indexできるように)、標準入力の行列(H,W)を読み込んでいくのですが、

[code]

    H,W = map(int,input().split())
    
    table = [[0]*(W+1) for i in range(H+1)]
    
    for row in range(H):
        work = list(map(int,input().split())) #★★直にtableに代入すると、列数が変わってしまう!!!★★★
        for col in range(W):
            table[row][col] = work[col]
    
[/code]

ここで上記のコメントにあるように

[code]

    work = list(map(int,input().split()))
    
[/code]

を除いた場合に何故、列数が変わってしまうのか分かりません。

解説していただける方いらっしゃいましたら、よろしくお願い致します。

参考程度に解答例のコード全体も以下に載せておきます。

[code]

    H,W = map(int,input().split())
    
    table = [[0]*(W+1) for i in range(H+1)]
    
    for row in range(H):
        work = list(map(int,input().split())) #★★直にtableに代入すると、列数が変わってしまう!!!★★★
        for col in range(W):
            table[row][col] = work[col]
    
    
    for row in range(H):
        for col in range(0,W):
            table[row][W] += table[row][col]
    
    
    for col in range(0,W+1):
        for row in range(0,H):
            table[H][col] += table[row][col]
    
    
    for row in range(0,H+1):
        print("%d"%(table[row][0]),end="")
        for col in range(1,W+1):
            print(" %d"%(table[row][col]),end = "")
        print()
    
[/code]


CC BY-SA 4.0
2020-03-29T04:08:02.967
65194
2020-03-29T22:59:34.577
2020-03-29T05:12:14.770
36869
36869
question
python python3
2次元の零行列に数値を代入していく時のコードに関して


リンク先の出題にあるSample Inputを元にして説明します。

### Sample Input

[code]

    4 5
    1 1 3 4 5
    2 2 2 4 5
    3 3 0 1 1
    2 3 4 4 6
    
[/code]

1行目の`4 5`を`H, W`に読み込んだ後に

[code]

    table = [[0]*(W+1) for i in range(H+1)]
    
[/code]

を実行すると、`table`の中身は次のようにネストしたリスト(いわゆる二次元配列)になります。

[code]

    [[0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0] #← 各列の合計を書き込む行
    ] #              ↑各行の合計を書き込むための列
    
[/code]

出題の指定通りに各列の合計のための行、各行の合計のための列が付け足された(4+1)行(5+1)列の二次元配列が作られます。

さて、「直にtableに代入する」と言うのは、こう言うことを言っているのだと思われます。

[code]

    for row in range(H):
        table[row] = list(map(int,input().split()))
    
[/code]

最初の1行分`1 1 3 4 5`を読み込むと`list(map(int,input().split()))`の値は`[1, 1, 3, 4,
5]`と言う5要素のリストになるわけですから、途中結果は以下のようになります。

[code]

    [[1, 1, 3, 4, 5],   #←この行が`table[0]`だから、`table[0]`が`[1, 1, 3, 4, 5]`に置き換えられる
     [0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0] #← 各列の合計を書き込む行
    ] #              ↑各行の合計を書き込むための列
    
[/code]

ご覧のように1行目からは、行の合計を保持するための6番目の要素がなくなってしまいます。

4行分全部実行完了すると、こんな感じですね。

[code]

    [[1, 1, 3, 4, 5],
     [2, 2, 2, 4, 5],
     [3, 3, 0, 1, 1],
     [2, 3, 4, 4, 6],
     [0, 0, 0, 0, 0, 0] #← 各列の合計を書き込む行
    ] #              ↑各行の合計を書き込むための列
    
[/code]

ご覧のように1〜4行目については、「列数が変わってしまう」と言うことになります。

* * *

先に「いわゆる二次元配列」と言う書き方をしましたが、Pythonの場合、リストのリストであり、外側のリストの各要素が全部同じ長さのリストになるようにして、擬似的に「二次元配列」として使っているだけに過ぎません。

外側のリストの各要素を書き換えて、別の長さのリストにしてしまうことができる(なんならリスト以外のものに書き換えることもできる)と言うことがわかれば、「列数が変わってしまう」と言う挙動も理解できるのではないかと思うのですが、いかがでしょうか?


CC BY-SA 4.0
2020-03-29T18:31:13.410
65211
2020-03-29T22:59:34.577
2020-03-29T22:59:34.577
13972
13972
65194
answer