본문 바로가기

프로그래밍/Coding

[기초문법] zip()의 활용 (feat. 행렬 전치)

" 파이썬의 마법 도구, zip() 함수 완벽 정리: 기초부터 행렬 전치까지 "
파이썬에서 여러 개의 리스트를 동시에 다루거나, 행렬의 모양을 바꿀 때 zip()만큼 유용한 함수는 없습니다. 오늘은 이 함수의 기초 사용법부터 고급 테크닉인 '행렬 전치(Transpose)'까지 핵심 코드 위주로 살펴보겠습니다.
zip() 함수란?
names = ["Alice", "Bob", "Charlie"]
scores = [85, 92, 78]

# 두 리스트를 하나로 묶기
for name, score in zip(names, scores):
    print(f"{name}: {score}")

# 결과:
# Alice: 85
# Bob: 92
# Charlie: 78
  • zip():
    • 여러 개의 순회 가능한(iterable) 객체를 인자로 받아,
    • 각 객체의 동일한 인덱스에 있는 요소들을 튜플(tuple) 형태로 묶어주는 이터레이터를 반환. 
  • 예시) zip(names, scores) 
    • names와 scores의 인덱스를 앞에서부터 하나씩 순회하며 동일한 자리의 값을 묶음 
    • ("Alice", 85), ... 
주의점 : 길이가 다른 리스트를 묶을 때 
  • zip()은 기본적으로 가장 짧은 리스트의 길이에 맞춰 동작. 나머지 데이터는 버려짐 
  • 대안 : itertools.zip_longest ; 부족한 부분은 fillvalue로 채울 수 있음 
    • 옵션 ; fillvalue= '-'
from itertools import zip_longest

list1 = [1, 2, 3]
list2 = ['A', 'B']

print(list(zip(list1, list2))) 
# 결과: [(1, 'A'), (2, 'B')] -> 3은 사라짐

print(list(zip_longest(list1, list2, fillvalue='-')))
# 결과: [(1, 'A'), (2, 'B'), (3, '-')]
Zip Unpacking : 묶인 데이터를 다시 풀기 
pairs = [(1, 'a'), (2, 'b'), (3, 'c')]

# Unzipping
numbers, letters = zip(*pairs)

print(numbers) # (1, 2, 3)
print(letters) # ('a', 'b', 'c')
  • zip()으로 묶은 데이터 앞에 별표(*) 연산자를 붙이면 다시 원래의 리스트 형태로 풀수 있음 
  • numbers, letters = zip(*pairs) : zip으로 묶기전 두개의 배열로 분리 
핵심 테크닉: 행렬 전치(Transpose)
  • zip()의 진가는 2차원 리스트(행렬)의 행과 열을 바꿀 때 나타납니다. 
  • zip(*matrix) 패턴은 알고리즘 문제 풀이에서 매우 자주 사용됩니다.
    • ex) 세로로 문자열 읽기 등 

수학적으로 행렬 A를 A^T로 만드는 과정

matrix = [
    [1, 2, 3],
    [4, 5, 6]
]

# 행렬 전치 (Transpose)
transposed = list(zip(*matrix))

print(transposed)
# 결과: [(1, 4), (2, 5), (3, 6)]
  • *matrix는 2차원 리스트 내부의 각 행(리스트)을 개별적인 인자로 풀어줍니다. 
    • 기존 : zip( [ [1, 2, 3], [4, 5, 6] ] ) => 하나의 배열로 zip에 들어가기에 zip() 불가능 
    • *matrix : zip( [1, 2, 3], [4, 5, 6] ) => 두개의 배열로 zip에 인자로 사용 가능
  • zip은 각 리스트의 첫번째 요소인 (1, 4), 두 번째인 (2, 5) .. 등을 차례로 묶습니다. 
  • 결과적으로 기전의 열이 새로운 행이 되는 전치 행렬이 완성됩니다. 
관련 문제