
파이썬에서 튜플이나 리스트를 다루다 보면 자연스럽게 data[0], data[1], data[2] 같은 인덱싱에 손이 갑니다. 다른 언어에서 배열 쓰던 습관입니다. 그런데 이 코드가 쌓이다 보면 "1번이 뭐였지?"를 자꾸 다시 확인하게 됩니다. 변수명에 의미가 담기지 않으니 매번 튜플 구조를 기억해야 합니다.
파이썬은 언패킹(unpacking)이라는 아주 우아한 문법을 제공합니다. 좌변에 여러 변수를 두고 우변의 시퀀스를 한 번에 풀어내는 것입니다. 이걸 알고 나면 인덱싱으로 꺼내 쓰던 코드가 초라해 보입니다.
snack_calories = {
'chips': 140,
'popcorn': 80,
'nuts': 190,
}
items = tuple(snack_calories.items())
# 인덱스로 일일이 꺼내기
first_item = items[0]
first_name = first_item[0]
first_calories = first_item[1]
print(f'{first_name}은 {first_calories}kcal')
# 두 변수 값 교환할 때도 임시 변수 만들기
a = 1
b = 2
tmp = a
a = b
b = tmp
first_item[0], first_item[1]만 봐서는 이게 이름인지 칼로리인지 알 수가 없습니다. 변수 교환도 C 스타일로 임시 변수를 쓰면 3줄이 필요합니다. 파이썬다운 코드는 아닙니다.
# 튜플을 이름 있는 변수로 한 번에 풀기
name, calories = ('popcorn', 80)
print(f'{name}은 {calories}kcal')
# 변수 교환은 한 줄로
a, b = b, a
# for 루프에서 특히 빛난다
for rank, (name, calories) in enumerate(snack_calories.items(), 1):
print(f'{rank}위: {name} ({calories}kcal)')
# 별표(*)로 가운데나 끝 묶기
first, *middle, last = [1, 2, 3, 4, 5]
# first=1, middle=[2,3,4], last=5
name, calories = ...라고 쓰는 순간 코드 자체가 문서가 됩니다. 인덱스를 외울 필요가 없습니다. a, b = b, a는 우변이 먼저 튜플로 만들어진 뒤 좌변에 풀리기 때문에 임시 변수 없이도 안전하게 교환됩니다. 특히 for 루프에서 딕셔너리의 items()나 enumerate()를 풀어 쓸 때는, 언패킹 없이는 거의 코드가 성립이 안 될 정도로 자주 쓰입니다.
[0], [1]로 꺼내는 대신 name, value = pair처럼 언패킹합니다.a, b = b, a 한 줄이면 끝입니다. 임시 변수는 필요 없습니다.for rank, value in enumerate(...), for key, value in dict.items()처럼 반복문에서 특히 자주 씁니다.first, *rest = items처럼 별표(*)로 나머지를 한 번에 묶을 수 있습니다.ValueError가 납니다.데이터 분석을 할 때 pandas의 df.iterrows()나 df.itertuples(), CSV 리더가 반환하는 행을 다룰 때 언패킹이 빛납니다. for idx, row in df.iterrows():처럼 말입니다. 또 함수에서 여러 값을 튜플로 반환할 때(return total, mean, std 같은 경우), 호출부에서 total, mean, std = stats(data)로 받으면 API가 자기 설명적이 됩니다. 웹 개발에서도 URL 라우팅의 경로 파라미터를 받거나, socket.recvfrom()이 반환하는 (data, addr) 쌍을 처리할 때 인덱싱으로 꺼내는 코드보다 언패킹이 훨씬 가독성이 좋습니다.