코테를 풀다보면
[[1,2]
[3,4]] 를
[[1,3]
[2,4]]로 바꾸고 싶을때가 있다.
물론 코딩을 통해 하나씩 옮겨주는 방법도 있지만 문제는 이런 사소한 부분들을 신경쓰다보면 이상하게 말리는 경우가 생긴다는 것이다.
python 행렬 전치를 구글링하면 numpy를 사용하여 전치하는 예시들이 나오는데, 코딩테스트에서는 이런 외부 라이브러리를 사용하지 못하는 경우가 발생한다. 이때를 대비하기 위해 행렬을 다루는 방법을 알아본다.
행렬 전치하기
a = [ [1,2] , [3,4] ]
b = list(zip(*a))
for tmp in b:
print(tmp)
# (1,3)
# (2,4)
zip(*배열) 을 사용해주면 간단히 행과 열을 바꿔줄 수 있다.
행렬 회전하기
방금 우리는 zip을 통해 행렬을 전치하는 방법을 익혔다. 우리는 이 방법을 통해 행렬을 회전시킬 수 있다.
만약 행렬을 회전하고 싶다면 직접 for 구문을 통해 기존에 있는 배열의 값을 일일히 옮겨주어야했다. 그러나 zip을 쓰면 아주 간단히 회전시킬 수 있다.
for i in range(m):
for j in range(n):
tmp[i][j] = arr[n-1-j][i]
arr = list(map(list, zip(*arr[::-1]))) # 시계방향으로 회전
arr = list(map(list, zip(*arr)))[::-1] # 반시계방향으로 회전
실제 결과값을 보면 zip을 이용하여 간단하게 회전시킬 수 있다.
추가적인 궁금증
그럼 *은 무슨 역할을 하길래 zip에다가 파라미터로 넣어줄때 사용하는가?
우선 *의 역할을 알아봐야한다. 파이썬 에서 *은 다양한 역할을 하게 된다.
- 곱셈
- 리스트 확장
- 가변인자
- unpacking
a = [[1,2], [3,4]]
print(*a)
# [1,2] [3,4]
*의 역할은 함수에 들어갈때 여러 인자로 들어가게 되거나 아니면 구조를 분해하여 할당하는 경우 사용된다.
원래 zip 함수는 2개이상의 인자가 들어가야한다.
list(zip([1,2],[3,4]))
# [(1, 3), (2, 4)]
list(zip([1,2],[3,4],[5,6]))
# [(1, 3, 5), (2, 4, 6)]
원래 zip이란 함수 자체가 각 iterable한 객체를 짝지어 주는 역할을 하기 위해 존재하기 때문에 결국 짝짓기 위해서는 여러개의 파라미터가 할당되어야 한다.
그래서 우리는 zip(a) 를 통해 리스트를 쪼개서 넣게 되는 것이다. 그럼 쪼개진 리스트가 서로 조합되다 보니 행열이 전치되는 형태로 작동하게 된다.
즉, zip(a) => zip([1,2], [3,4]) 라는 것이다.
그럼 짝을 지어 반환되니까 zip([1,2], [3,4]) => [1,3],[2,4] 로 짝지어지고 zip객체로 반환되는 것이다.
파이썬이란 참 유연하고 신기한거 같다.
'삽질방지' 카테고리의 다른 글
[python3] 문자열 형변환 (int, float, str, chr, ord) (0) | 2022.03.09 |
---|---|
spring builder 오류 (error: cannot find symbol final .......) (0) | 2022.03.03 |
[python3] binary string to integer, integer to binary string (0) | 2022.02.17 |
파이썬 재귀 제한 풀기 (0) | 2022.02.16 |
정규표현식 (0) | 2021.09.02 |