프로그래머스에서 1단계를 오늘 많이 풀어보자는 생각으로 풀고 있었는데, 생각보다 시간이 오래 걸린 문제가 있었다.
문제는 다음과 같다.
[문제] 행렬의 덧셈은 행과 열의 크기가 같은 두 행렬의 같은 행, 같은 열의 값을 서로 더한 결과가 됩니다. 2개의 행렬 arr1과 arr2를 입력받아, 행렬 덧셈의 결과를 반환하는 함수, solution을 완성해주세요. |
단순히 행렬을 새로 제작하여 삽입하는 방식을 이용하려 했으나 실행이 되지 않았다. 그래서 인터넷에 검색해본 결과 numpy를 이용한 방법 또는 arr1 += arr2 를 이용하여 arr1을 반환하는 방법이 있었다. 후자의 방법을 차용하여 실행하고 다른 사람들의 코드를 보고 있었는데 이해하기 어려운 코드를 발견했다. 그 코드는 아래와 같다.
다른 코드들은 list comprehension을 이용하는 방식인데 반해 위의 코드는 list comprehension과 map을 이용했다. 특히 이해하기 어려운 부분은 map(sum, zip(*x)) 부분이다. 이 부분이 도대체 어떻게 작동이 되는지 감이 잡히질 않았다. 따라서, pycharm의 디버거를 이용하여 해당 코드를 면밀히 분석했고 미흡하지만 이해할 수 있었다.
1. list comprehension 에서 행렬 arr1 과 arr2 를 zip으로 묶는다. 각 원소끼리 묶인다.
2. zip으로 묶인 값을 이용하여 zip의 값을 합친다.
이 부분이 가장 이해하기 어려웠다. map(sum, zip(*x))에서 map이 두개의 원소를 이용하고 좌측에는 공식을, 우측에는 해당 공식을 이용할 요소를 삽입한다는 부분은 알고 있었다. 그러나, *x ...? 도대체 C도 아닌데 *이 왜 있는 것인지 이해가 안되어 이에 대해 검색했다.
검색해보니 *은 네가지의 역할이 있다고 한다.
- 곱셈 및 거듭제곱 연산으로 사용할 때
- 리스트형 컨테이너 타입의 데이터를 반복 확장하고자 할 때
- 가변인자를 사용하고자 할 때
- 컨테이너 타입의 데이터를 Unpacking 할 때
이 중 map(sum, zip(*x))에서 사용된 성질은 '컨테이너 타입의 데이터를 Unpacking하는 경우'였다.
근데 아직 잘 이해안된다.... 이 부분은 추가로 공부해야 할 거 같다. 방금 다시 pycharm을 이용해서 *x에서 *를 제거하여 실행해보니 오류가 발생한다. 해당 오류는 unsupported operand type(s) for +: 'int' and 'list' 로 *를 이용하지 않으면 zip(x)는 리스트로 분류되어 sum 연산이 안되는 것으로 보인다. 왜 이용 하는 지는 알게 되었으나 아직 개념에 대해서는 잘 모르겠으니 꼭 추후에 공부하도록 하자.
- list comprehension
- lambda
- asterisk(*)
- map
- zip
- reduce
- numpy 등 외부 라이브러리
코드 참조: 프로그래머스
Asterisk 참조: https://mingrammer.com/understanding-the-asterisk-of-python/
[프로그래머스] 다단계 칫솔 (0) | 2021.12.30 |
---|---|
[프로그래머스] 최대공약수와 최소공배수 (0) | 2021.12.29 |
[프로그래머스] 자연수 뒤집어 배열로 만들기 (0) | 2021.12.28 |
[프로그래머스] 소수 만들기 (0) | 2021.12.23 |
[프로그래머스] 약수의 개수와 덧셈 풀이 (0) | 2021.12.23 |
댓글 영역