解答例_4_6

解答例:練習問題_4_6 内包表記 (行列の積)

# A(3行4列) B(4行4列)の行列を作成
A = [[10*i + j for j in range(4)] for i in range(3)]
B = [[10*i + j for j in range(4)] for i in range(4)]
print('A:', A)
print('B:', B)

# AとBの行列の積
AB = [[sum([A[i][k] * B[k][j] for k in range(len(A[0]))])
    for j in range(len(B[0]))] for i in range(len(A))]
print('AB:', AB)

A: [[0, 1, 2, 3], [10, 11, 12, 13], [20, 21, 22, 23]]
B: [[0, 1, 2, 3], [10, 11, 12, 13], [20, 21, 22, 23], [30, 31, 32, 33]]
AB: [[140, 146, 152, 158], [740, 786, 832, 878], [1340, 1426, 1512, 1598]]

ABの内包表記は三重のforループとなり長いので途中で一度改行しています。(括弧内であれば自由に改行が可能です)
最初の行の sum([A[i][k] * B[k][j] for k in range(len(A[0]))]) でAの i行ベクトルとBの j列ベクトルの内積を計算しています。
例えば iと jが共に0の時、[A[0][k] * B[k][0] for k in range(len(A[0]))]は、[0*0, 1*10, 2*20, 3*30] を表すリストとなります。それを合計を取る関数 sum() の括弧に入れることで、0*0 + 1*10 + 2*20 + 3*30 = 140 を計算しています。
それを for j in range(len(B[0])) で行方向に列数分繰り返しリスト化、さらにそれをfor i in range(len(A)) で列方向に行数分繰り返してリスト化してABを作成しています。
ちなみにlen(A[0])はAの0行目の長さをAの列数として、len(B[0])はBの0行目の長さをBの列数として、len(A)はAの行数としてそれぞれ使用しています。

タイトルとURLをコピーしました