2차원 행렬 arr1과 arr2를 입력받아, arr1에 arr2를 곱한 결과를 반환하는 함수, solution을 완성해주세요.
| arr1 | arr2 | return |
|---|---|---|
[[1, 4], [3, 2], [4, 1]] | [[3, 3], [3, 3]] | [[15, 15], [15, 15], [15, 15]] |
[[2, 3, 2], [4, 2, 4], [3, 1, 4]] | [[5, 4, 3], [2, 4, 1], [3, 1, 1]] | [[22, 22, 11], [36, 28, 18], [29, 20, 14]] |
def solution(arr1, arr2):
answer = [[] for _ in range(len(arr1))]
for i in range(len(arr1)):
for j in range(len(arr2[0])):
total = 0
for row_num, col in zip(arr1[i], arr2):
total += (row_num * col[j])
answer[i].append(total)
return answer
(고등학교 교육 과정이 개편되면서 행렬을 안 배워서 행렬을 배우고, 그 방식을 구현하느로 꽤나 애를 잡았다.)
행렬의 곱셈 방식이 꽤나 특이하다고 할 수 있다(사실 이거 이해하는데만 꽤나 오랜 시간이 필요했다).
이렇다 보니 arr1에서 행을 가져오고, arr2에서는 열을 가져와 그 둘끼리 곱한 값을 더해야 한다는 건데, 생각이 턱하고 막혔었다.
그 방법을 고민하다 생각난 접근법이 다음과 같다.
arr1에서 행의 인덱스를 가져온다.arr2에서 열의 인덱스를 가져온다.arr1의 한 행의 각 숫자들을 arr2의 한 행끼리 연결시킨다.answer의 (1번에서 가져온 값)행에 새로 push한다.입출력 예의 2번을 예시로 설명하면......
arr[i]는 [2, 3, 2]이다.zip 내장 함수를 통해 arr2와 엮는다.row_num이 2일 때, col은 [5, 4, 3]이 된다.row_num이 3일 때, col은 [2, 4, 1]이 된다.row_num이 2일 때, col은 [3, 1, 1]이 된다.j는 0이다.row_num이 2일 때, row_num * col[j]는 10이다.row_num이 3일 때, row_num * col[j]는 6이다.row_num이 2일 때, row_num * col[j]는 6이다.total은 22이다.return 행렬에서 첫 번째 행의 첫 번째 열의 값을 구한 것이다.answer[i]는 현재 첫 번째 행을 가리키므로, 이 값을 push하면 된다.이 과정을 풀이에 맞게 반복하면 전체적인 행렬의 곱셈을 구할 수가 있다.
def solution(A, B):
return [[sum(a*b for a, b in zip(A_row,B_col)) for B_col in zip(*B)] for A_row in A]
(역시 파이썬... 최적의 코드는 언제나 한 줄인 것인가?)
*B가 나에게는 어색한 문법이다. 실제로 *[[5, 4, 3], [2, 4, 1], [3, 1, 1]] 값을 찍어보니 다음과 같이 출력된다.
[5, 4, 3] [2, 4, 1] [3, 1, 1]
기본적으로 print의 sep가 공백 문자인 것을 감안하면 세 개의 배열이 출력되었다는 것이다.
그렇다면, 이걸 zip으로 묶으면 같은 열에 위치한 값들끼리 묶을 수 있다.
고로, 행렬을 조금 더 쉽게 구할 수 있게 된다는 것을 의미한다.