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
으로 묶으면 같은 열에 위치한 값들끼리 묶을 수 있다.
고로, 행렬을 조금 더 쉽게 구할 수 있게 된다는 것을 의미한다.