이름과 점수를 별도 리스트로 받았다고 가정해 보겠습니다. 같은 위치의 원소를 함께 처리할 때는 zip()이 편리해요. 다만 두 리스트의 길이가 다를 때 어떤 결과가 필요한지 먼저 정해야 합니다.
names = ["Ara", "Min", "Jun"]
scores = [90, 80]
print(list(zip(names, scores)))
[('Ara', 90), ('Min', 80)]
Jun은 결과에 포함되지 않습니다. 기본 zip()은 가장 짧은 입력이 끝나면 함께 종료하기 때문이에요. 짝이 있는 데이터만 필요하다면 적절하지만, 모든 학생에게 점수가 있어야 한다면 누락을 놓칠 수 있습니다.
Python 3.10부터는 길이 불일치를 오류로 드러낼 수 있습니다.
names = ["Ara", "Min", "Jun"]
scores = [90, 80]
try:
pairs = list(zip(names, scores, strict=True))
except ValueError:
print("length mismatch")
length mismatch
중요한 점은 zip()이 이터레이터라는 사실입니다. 실제로 원소를 꺼내는 과정에서 불일치를 발견해요. zip(..., strict=True) 객체만 만들었다고 모든 길이가 검증된 것은 아닙니다. 중간에 반복을 멈추면 불일치가 드러나지 않을 수도 있어요.
파일 저장처럼 되돌리기 어려운 작업을 반복문 안에서 한다면, 길이 오류가 나기 전에 일부 작업이 이미 실행될 수도 있습니다. 작은 데이터라면 위처럼 먼저 리스트로 만들어 검증한 뒤 후속 작업을 하는 방법을 고려할 수 있어요.
from itertools import zip_longest
names = ["Ara", "Min", "Jun"]
scores = [90, 80]
print(list(zip_longest(names, scores, fillvalue=None)))
[('Ara', 90), ('Min', 80), ('Jun', None)]
zip_longest()는 긴 입력이 끝날 때까지 진행하면서 부족한 자리를 지정한 값으로 채웁니다. 다만 실제 데이터에도 None이 들어갈 수 있다면, 저장된 None과 누락을 구분할 기준이 따로 필요합니다.
길이 검사는 개수만 확인합니다. 이름이 ["Ara", "Min"], 점수가 Min과 Ara 순서로 전달되었다면 길이가 같아도 잘못 연결됩니다. 서로 독립적으로 조회한 데이터라면 위치가 아니라 학생 ID 같은 공통 키로 연결해야 할 수 있어요.
정리하면, 짝이 있는 부분만 쓸지, 불일치를 오류로 볼지, 누락을 표시할지부터 결정하면 됩니다. zip()의 선택보다 먼저 정할 것은 데이터 누락의 의미입니다.