본문으로 건너뛰기

딕셔너리: 키로 찾기

파이썬 목차딕셔너리와 집합레슨 32 / 59

목차

딕셔너리(dictionary)는 키(key)와 값(value)을 한 쌍씩 담아 두고 키로 값을 찾는 묶음입니다. 메뉴판에서 메뉴 이름을 대면 가격이 나오듯, 키를 대면 그 키와 한 쌍인 값이 나옵니다.

리스트는 자리 번호로 값을 꺼냅니다. 라테 가격을 꺼내려면 라테가 몇 번 칸인지부터 알아야 하고, 메뉴가 늘면 번호도 달라집니다. 딕셔너리는 메뉴 이름을 키로 삼아 번호 없이 바로 찾습니다.

이 단원(딕셔너리와 집합)을 이미 안다면 단원 연습 문제부터 풀고 틀린 레슨만 보세요.

7단계 중 1단계. 다음을 누르면 1번 줄부터 실행합니다.

1키로 값을 꺼낸다

딕셔너리는 중괄호 {} 안에 키: 값을 쉼표로 이어 써서 만듭니다. 아래 1~4번 줄은 한 문장이고, 폰 화면에 맞게 한 쌍씩 줄을 나눴습니다.

menu = {
    '커피': 4000,
    '라테': 4500,
}
print(menu['라테'])
print(menu)
실행 결과
4500
{'커피': 4000, '라테': 4500}

1번 줄은 키 '커피'와 값 4000, 키 '라테'와 값 4500을 한 쌍씩 담은 딕셔너리를 만들고, 그 딕셔너리에 이름 menu를 붙입니다. 그림의 값 칸 머리에 적힌 dict가 딕셔너리의 종류 이름입니다. 5번 줄 menu['라테']는 대괄호 안의 키 '라테'로 그 키의 값 4500을 꺼냅니다. 6번 줄처럼 딕셔너리를 통째로 찍으면 중괄호와 콜론까지 찍힙니다.

리스트에서처럼 대괄호에 자리 번호 0을 쓰면 무엇이 찍힐까요?

menu = {
    '커피': 4000,
    '라테': 4500,
}
print(menu[0])
실행 결과 보기
실행 결과
Traceback (most recent call last):  File "main.py", line 5, in <module>    print(menu[0])          ~~~~^^^KeyError: 0

예상과 다르면 그곳이 배울 곳입니다. 딕셔너리는 대괄호 안의 값을 늘 키로 봅니다. 맨 아래 줄 KeyError: 0은 0이라는 키가 없다는 뜻입니다. 딕셔너리의 쌍에는 자리 번호가 없습니다.

2담기와 바꾸기 — 키는 하나

대괄호에 키를 쓴 menu['쿠키']를 =의 왼쪽에 두면, 그 키와 오른쪽 값을 한 쌍으로 담습니다.

menu = {
    '커피': 4000,
    '라테': 4500,
}
menu['쿠키'] = 2000
menu['라테'] = 5000
print(menu['라테'], menu['쿠키'])
print(len(menu))
실행 결과
5000 2000
3

5번 줄의 '쿠키'는 없던 키라서 쌍이 하나 늡니다. 6번 줄의 '라테'는 이미 있는 키입니다. 키는 한 딕셔너리 안에 하나뿐이라 쌍이 늘지 않고 키 '라테'의 값만 5000으로 바뀌어, len(menu)는 쌍의 수 3입니다. 이름을 다른 값에 다시 붙이면 옛 연결이 끊기듯, 키가 새 값과 한 쌍이 되면 옛 값 4500과의 연결이 끊깁니다(규칙 3).

3없는 키 — KeyError와 get()

없는 키를 대괄호로 꺼내면 오류가 납니다.

menu = {
    '커피': 4000,
    '라테': 4500,
}
key = '빙수'
print(menu[key])
실행 결과
Traceback (most recent call last):  File "main.py", line 6, in <module>    print(menu[key])          ~~~~^^^^^KeyError: '빙수'

맨 아래 줄부터 읽습니다. KeyError는 그런 키가 없다는 오류이고, 찾던 키 '빙수'를 함께 찍어 줍니다. 키가 없을 수도 있으면 get()을 씁니다. 키가 없을 때 오류 대신 둘째로 넘긴 값, 곧 기본값(default value)을 돌려줍니다.

menu = {
    '커피': 4000,
    '라테': 4500,
}
print(menu.get('빙수', 0))
print(menu.get('빙수'))
실행 결과
0
None

5번 줄은 키 '빙수'가 없어 기본값 0을 돌려받아 찍습니다. 6번 줄처럼 기본값을 넘기지 않으면 None을 돌려줍니다. None은 돌려줄 값이 없다는 뜻의 값이라 수처럼 더할 수 없습니다. 꺼낸 값으로 계산할 때는 0 같은 기본값을 함께 넘깁니다.

예제

있는 값을 올리기

커피 가격을 200원 올립니다. 키의 값을 꺼내 계산한 뒤 같은 키에 다시 담습니다.

menu = {
    '커피': 4000,
    '라테': 4500,
}
menu['커피'] = menu['커피'] + 200
print(menu['커피'])
실행 결과
4200

5번 줄은 오른쪽부터 계산합니다(규칙 2). menu['커피']로 꺼낸 4000에 200을 더한 4200을 만들고, 그 값을 키 '커피'와 다시 한 쌍으로 담습니다. 세기: 메뉴별로 모으기 레슨은 이 꼴로 메뉴마다 개수를 셉니다.

자주 틀리는 곳

틀린 생각: 딕셔너리도 리스트처럼 0번, 1번 자리 번호로 꺼낼 수 있다.

리스트도 딕셔너리도 대괄호로 꺼내서 같은 일로 보입니다. 딕셔너리의 대괄호 안은 자리 번호가 아니라 키입니다.

menu = {'커피': 4000}
print(menu[0])
실행 결과
Traceback (most recent call last):  File "main.py", line 2, in <module>    print(menu[0])          ~~~~^^^KeyError: 0

0이라는 키가 없어 KeyError가 납니다. 첫 쌍의 값 4000이 나오지 않습니다.

맞는 규칙: 딕셔너리는 대괄호 안의 값을 키로 찾고, 쌍에는 자리 번호가 없습니다. 값은 menu['커피']처럼 키로 꺼냅니다.

틀린 생각: 이미 있는 키에 다시 담으면 같은 키의 쌍이 하나 더 생긴다.

리스트는 append()로 같은 값을 더해도 칸이 늘어서, 딕셔너리도 담을 때마다 쌍이 늘 것처럼 보입니다.

menu = {'커피': 4000}
menu['커피'] = 4200
print(menu)
print(len(menu))
실행 결과
{'커피': 4200}
1

2번 줄은 키 '커피'의 값을 4200으로 바꿀 뿐이라 쌍은 여전히 하나입니다.

맞는 규칙: 키는 한 딕셔너리 안에 하나뿐이라, 이미 있는 키에 담으면 그 키의 값이 새 값으로 바뀌고 옛 값과의 연결은 끊깁니다(규칙 3).

확인 문제

1. 2절 코드의 5번 줄 키를 '쿠키'에서 '커피'로 바꾸고, 7번 줄도 그에 맞췄습니다. 무엇이 찍히는지 두 줄을 글자 그대로 쓰세요.

menu = {
    '커피': 4000,
    '라테': 4500,
}
menu['커피'] = 2000
menu['라테'] = 5000
print(menu['라테'], menu['커피'])
print(len(menu))
힌트

5번 줄과 6번 줄의 키가 1번 줄 딕셔너리에 이미 있는지 봅니다.

정답
실행 결과
5000 2000
2

5번 줄의 '커피'와 6번 줄의 '라테'는 둘 다 이미 있는 키라서 값만 2000과 5000으로 바뀝니다. 쌍은 처음 그대로 둘입니다.

흔한 오답은 둘째 줄을 4로 쓰는 것입니다. 담을 때마다 쌍이 하나씩 는다고 본 것입니다(상자 생각). 키는 한 딕셔너리 안에 하나뿐입니다(규칙 3).

2. 쿠키 값을 500원 올려 찍으려 합니다. 1~4번 줄의 쿠키 값이 2000이면 2500, 3000이면 3500이 찍혀야 합니다. 6번 줄의 빈칸을 채우세요.

menu = {
    '커피': 4000,
    '쿠키': 2000,
}
price = menu['쿠키']
menu['쿠키'] = ________
print(menu['쿠키'])
힌트

5번 줄에서 이름 price가 어느 값에 붙는지 먼저 적어 봅니다.

정답

price + 500입니다.

menu = {
    '커피': 4000,
    '쿠키': 2000,
}
price = menu['쿠키']
menu['쿠키'] = price + 500
print(menu['쿠키'])
실행 결과
2500

5번 줄이 키 '쿠키'의 값 2000을 꺼내 그 값에 이름 price를 붙이고, 6번 줄이 2000에 500을 더한 2500을 키 '쿠키'와 다시 한 쌍으로 담습니다.

다르게 써도 되는 곳: 500 + price나 menu['쿠키'] + 500도 같습니다.

빈칸에 2500을 바로 써도 2500이 찍히지만, 쿠키 값이 3000이면 3500이 아니라 2500이 그대로 찍힙니다. 지금 값을 꺼내 더해야 따라 바뀝니다.

흔한 오답은 500만 쓰는 것입니다. 그러면 키 '쿠키'의 값이 500으로 바뀌어 500이 찍힙니다. 500을 담으면 지금 값 2000에 더해진다고 본 것입니다(상자 생각). 올리려면 지금 값에 더해야 합니다.

3. 과목별 점수를 딕셔너리에 적었습니다. 무엇이 찍히는지 세 줄을 글자 그대로 쓰세요.

score = {'국어': 80, '수학': 70}
score['수학'] = 90
score['영어'] = 85
print(len(score))
print(score.get('과학', 0))
print(score['수학'])
힌트

2번 줄과 3번 줄의 키가 1번 줄 딕셔너리에 있던 키인지 가립니다. 5번 줄은 키 '과학'이 있는지 봅니다.

정답
실행 결과
3
0
90

2번 줄은 있던 키 '수학'의 값을 90으로 바꾸고, 3번 줄은 없던 키 '영어'를 담아 쌍이 셋이 됩니다. 5번 줄은 키 '과학'이 없어 기본값 0을 돌려줍니다.

흔한 오답은 첫 줄을 4로 쓰는 것입니다. 같은 키 '수학'에 담을 때도 쌍이 는다고 본 것입니다(상자 생각). 이미 있는 키에 담으면 값만 바뀝니다(규칙 3).

5번 줄의 키 '빙수'를 있는 키 '라테'로 바꾸면 찍히는 줄을 모두 봅니다.

처음 펼 때 약 6MB를 받습니다.컴퓨터에서 해 보기

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

파이썬 목차로