第19回【Python】行列の転置、かけ算表

現在取り組んでいるのは、paiza ラーニング問題集「二重ループメニュー」になります。

はじめに

猫とキャンプと野球観戦と AWS が大好きな旦那、LeoSaki です。モフモフしたい。

Python をゼロから勉強してみよう、のコーナー 19 回目です。

次でとうとう 20 回を迎えますか。どのくらい成長しただろう。ループ文をやってるあたり、まだまだ成長には程遠いですかね。ですが、LeoSaki(旦那)の作った AWS Lambda の Lambda 関数は着々と進化している模様。学んだことを即活かすことができると、楽しくなってきます。

それでは、今日も頑張ってみようと思います。

行列の転置

N 行 K 列の行列 A の i 行 j 列 の要素 A_ij を A_ji とした K 行 N 列の行列を元の配列 A の転置行列と言います。

例として、

1 2 3
4 5 6
7 8 9

の転置行列は

1 4 7
2 5 8
3 6 9

です。

行列 A についての情報が与えられるので、A の転置行列を出力してください。

いろんな場面でよくあるやつですね。出力された CSV が X 軸方向に商品、Y 軸方向に年月日となっているものを見にくいから X 軸方向に年月日、Y 軸報告に商品に入れ替えろ、みたいな感じ。

Python
N,K = map(int,input().split())
A = [input().split() for _ in range(N)]
for k in range(K):
    for n in range(N):
        if n == N-1:
            print(A[n][k])
        else:
            print(A[n][k],end=" ")

これは結構基本形な気がします。ただ、最初の頃はなかなかイメージつかなかったです。紙に [0][1] [1][1] [2][1] ってな感じで、書いていた記憶がある。

VBA でもやってみよう。

VBA
Dim tmp1() As Long, tmp2() As Long
S = Split(Cells(1, 1), " ")
N = Val(S(0))
K = Val(S(1))
ReDim tmp1(N - 1, K - 1)
ReDim tmp2(N - 1, K - 1)
For ro = 0 To N - 1
    S = Split(Cells(ro + 2, 1), " ")
    For co = 0 To K - 1
        tmp1(ro, co) = S(co)
    Next
Next
For ro = 0 To K - 1
    For co = 0 To N - 1
        tmp2(ro, co) = tmp1(co, ro)
    Next
Next
For ro = 0 To N - 1
    For co = 0 To K - 1
        If co = K - 1 Then
            Debug.Print tmp2(ro, co)
        Else:
            Debug.Print (tmp2(ro, co));
        End If
    Next
Next

書いていて後悔するレベルで面倒くさかった。2 つ目の For 文で Debug.print して終わらせようかとも思ったけれど、一応、最後まできちんと書いてみた。
どんどん VBA の面倒くささが、いや違う、多分、Python が便利なんだと思う。

かけ算表

配列 A の要素数 N とその要素 A_i (1 ≦ i ≦ N) が与えられるので、A についてのかけ算表 B を出力してください。かけ算表は N * N の二次元配列の形式とし、B の i 行 j 列の要素 B_ij について、B_ij = Ai * Aj (1 ≦ i , j ≦ N) が成り立つものとします。

例として、A = [1,2,3] のとき B は

1 2 3
2 4 6
3 6 9

となります。

なるほどなるほど。ってよくわからん。まぁ、問題文を読み解くのも学習のうちですしね。IPA の作る問題文ってそんなのばかりでしょ。あと、仕様書とか。

Python
N = int(input())
A = [int(x) for x in input().split()]
for i in range(N):
    for j in range(N):
        if j == N-1:
            print(A[i]*A[j])
        else:
            print(A[i]*A[j],end=" ")

さくっとこんな感じでいかがでしょうか。
問題文さえきちんと読み解くことが出来ればそんなに難しくはない。

まだ頑張れると信じて、VBA でも書いてみよう。

VBA
N = Cells(1, 1)
A = Split(Cells(2, 1), " ")
For i = 0 To N - 1
    For j = 0 To N - 1
        If j = N - 1 Then
            Debug.Print A(i) * A(j)
        Else
            Debug.Print A(i) * A(j);
        End If
    Next
Next

二次元配列を使うと面倒くさくなっちゃうんだろうか。なんだかあっさり書けてしまって拍子抜けだった。

最後に

LeoSaki(旦那)自身の得手不得手もあるのだと思う。VBA では二次元配列なんてほとんど使わなかったしなぁ。なんかあれば、セルに入れてやれば良いわけだし。VBA の二次元配列の扱い方が独特というのもある気がするけれど。

それにしても、Python って使いやすいですね。他の言語の数行を 1 行で書いてしまえるわけですし。あまりやりすぎると他のメンバーが読みづらくなるという問題もあると思うので、ほどほどに、とは思っています。

引き続き、お付き合いよろしくお願いいたします!

PythonPython,paiza,学習

Posted by LeoSaki