파이썬에는 값으로 이뤄진 불변(immutable) 순서쌍을 만들어낼 수 있는 tuple 내장타입이 있다.
가장 짧은 튜플은 딕셔너리의 키-값 쌍과 비슷하게 두 값으로 이뤄진다.
snack_calories = {
'감자칩': 140,
'팝콘': 80,
'땅콩': 190,
}
snack_calories
{'감자칩': 140, '팝콘': 80, '땅콩': 190}
items = tuple(snack_calories.items())
print(items)
(('감자칩', 140), ('팝콘', 80), ('땅콩', 190))
item = ('호박엿', '식혜')
first = item[0]
second = item[1]
print(first, '&', second)
호박엿 & 식혜
튜플은 인덱스를 통해 변경 불가능 (immutable)
pair = ('약과', '호박엿')
pair[0] = '타래과'
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-6-a813456798f0> in <module> 1 pair = ('약과', '호박엿') ----> 2 pair[0] = '타래과' TypeError: 'tuple' object does not support item assignment
파이썬에는 언패킹 구문이 있다.
item = ('호박엿', '식혜')
first, second = item # 언퍀킹
print(first, '&', second)
호박엿 & 식혜
인덱스 사용보다 시각적인 잡음이 적고, 이터러블이 들어간 경우 등 다양한 패턴을 언패킹 구문에 사용할 수 있다.
다음과 같은 코드는 추천하지는 않지만 가능하다는 사실을 알고 있는 것도 중요하다.
favorite_snacks = {
'짭조름한 과자': ('프레즐', 100),
'달콤한 과자': ('쿠키', 180),
'채소': ('당근', 20),
}
((type1, (name1, cals1)),
(type2, (name2, cals2)),
(type3, (name3, cals3))) = favorite_snacks.items()
print(f'제일 좋아하는 {type1} 는 {name1}, {cals1} 칼로리입니다.')
print(f'제일 좋아하는 {type2} 는 {name2}, {cals2} 칼로리입니다.')
print(f'제일 좋아하는 {type3} 는 {name3}, {cals3} 칼로리입니다.')
제일 좋아하는 짭조름한 과자 는 프레즐, 100 칼로리입니다. 제일 좋아하는 달콤한 과자 는 쿠키, 180 칼로리입니다. 제일 좋아하는 채소 는 당근, 20 칼로리입니다.
언패킹을 사용하면 임시 변수를 정의하지 않고도 값을 맞바꿀 수 있다.
다음은 오름차군 정렬 알고리즘이다.
def bubble_sort(a):
for _ in range(len(a)):
for i in range(1, len(a)):
if a[i] < a[i-1]:
temp = a[i]
a[i] = a[i-1]
a[i-1] = temp
names = ['프레즐', '당근', '쑥갓', '베이컨']
bubble_sort(names)
print(names)
['당근', '베이컨', '쑥갓', '프레즐']
언패킹 사용
def bubble_sort(a):
for _ in range(len(a)):
for i in range(1, len(a)):
if a[i] < a[i-1]:
a[i-1], a[i] = a[i], a[i-1]
names = ['프레즐', '당근', '쑥갓', '베이컨']
bubble_sort(names)
print(names)
['당근', '베이컨', '쑥갓', '프레즐']
우항 값이 임시 tuple에 들어가고 좌항에 임시 tuple의 값을 대입한다.
그 후 임시 tuple은 사라진다.
언패킹의 용례 중에서 또 한 가지 쓸모 있는 것으로 for 루프 또는 그와 비슷한 다른 요소(컴프리헨션이나 제너레이터 식)의 대상인 리스트의 원소를 언패킹하는 것이 있다.
snacks = [('베이컨', 350), ('도넛', 240), ('머핀', 190)]
for i in range(len(snacks)):
item = snacks[i]
name = item[0]
calories = item[1]
print(f'#{i+1}: {name} 은 {calories} 칼로리 입니다.')
#1: 베이컨 은 350 칼로리 입니다. #2: 도넛 은 240 칼로리 입니다. #3: 머핀 은 190 칼로리 입니다.
for rank, (name, calories) in enumerate(snacks, 1):
print(f'#{rank}: {name} 은 {calories} 칼로리입니다.')
#1: 베이컨 은 350 칼로리입니다. #2: 도넛 은 240 칼로리입니다. #3: 머핀 은 190 칼로리입니다.
pythonic한 방식이다.