[파이썬 개념 9] 딕셔너리와 튜플
리스트는 값을 번호로 꺼냅니다. 그런데 "푸름의 점수", "우유의 가격" 처럼 이름으로 꺼내고 싶을 때가 많습니다.
이럴 때 쓰는 것이 딕셔너리입니다. 이 글의 뒷부분에서는 리스트와 비슷하지만 바꿀 수 없는 튜플도 함께 알아봅니다.
1. 딕셔너리 만들기
딕셔너리는 키(이름)와 값을 짝지어 담습니다. 중괄호 { } 안에 키: 값 을 쉼표로 나누어 씁니다.
price = {"우유": 800, "빵": 1500, "주스": 1200}
print(price)
print(len(price))
실행 결과
{'우유': 800, '빵': 1500, '주스': 1200}
3
| 키 | 값 |
|---|---|
| "우유" | 800 |
| "빵" | 1500 |
| "주스" | 1200 |
국어사전에서 단어(키)를 찾으면 뜻(값)이 나오는 것과 같습니다. 그래서 이름도 딕셔너리(사전)입니다.
2. 키로 값 꺼내기
리스트의 [번호] 자리에 키를 씁니다.
price = {"우유": 800, "빵": 1500, "주스": 1200}
print(price["빵"])
print(price["우유"] + price["주스"])
실행 결과
1500
2000
없는 키를 꺼내면 오류가 납니다.
price = {"우유": 800, "빵": 1500}
print(price["라면"])
실행 결과
KeyError: '라면'
없을 수도 있는 키는 두 가지 방법으로 안전하게 꺼냅니다.
price = {"우유": 800, "빵": 1500}
item = "라면"
if item in price: # 방법 1: in 으로 먼저 확인
print(price[item])
else:
print("없음")
print(price.get(item, "없음")) # 방법 2: get(키, 없을 때 값)
print(price.get("빵", "없음"))
실행 결과
없음
없음
1500
3. 넣기, 바꾸기, 빼기
price = {"우유": 800}
price["빵"] = 1500 # 없는 키 → 새로 넣기
price["우유"] = 900 # 있는 키 → 값 바꾸기
print(price)
del price["빵"] # 빼기
print(price)
실행 결과
{'우유': 900, '빵': 1500}
{'우유': 900}
같은 대입 모양인데, 키가 없으면 추가, 있으면 덮어쓰기가 됩니다.
그래서 딕셔너리에는 같은 키가 두 개 있을 수 없습니다.
4. 반복문으로 꺼내기
| 모양 | 꺼내는 것 |
|---|---|
for k in 딕셔너리 |
키 |
for v in 딕셔너리.values() |
값 |
for k, v in 딕셔너리.items() |
키와 값 |
price = {"우유": 800, "빵": 1500, "주스": 1200}
for k in price:
print(k, end=" ")
print()
for k, v in price.items():
print(f"{k}: {v}원")
print(sum(price.values()))
실행 결과
우유 빵 주스
우유: 800원
빵: 1500원
주스: 1200원
3500
딕셔너리는 넣은 순서를 기억해서, 꺼낼 때도 그 순서대로 나옵니다.
5. 가장 많이 쓰는 패턴: 개수 세기
설문 응답에서 과목별 인원수를 세어 봅시다.
answers = ["수학", "국어", "수학", "정보", "정보", "수학"]
count = {}
for a in answers:
if a in count:
count[a] += 1 # 이미 있으면 1 더하기
else:
count[a] = 1 # 처음 보면 1로 넣기
print(count)
실행 결과
{'수학': 3, '국어': 1, '정보': 2}
get 을 쓰면 한 줄로 줄일 수 있습니다.
answers = ["수학", "국어", "수학", "정보", "정보", "수학"]
count = {}
for a in answers:
count[a] = count.get(a, 0) + 1
print(count)
실행 결과
{'수학': 3, '국어': 1, '정보': 2}
"없으면 0으로 보고 1을 더한다" 는 뜻입니다. pandas 의 value_counts() 가 해 주는 일이 바로 이것입니다.
6. 값으로 리스트 담기
값에는 무엇이든 담을 수 있습니다. 리스트를 담으면 표처럼 쓸 수 있습니다.
scores = {"국어": [80, 90, 70], "수학": [95, 85, 75]}
for subject, s in scores.items():
print(subject, sum(s) / len(s))
실행 결과
국어 80.0
수학 85.0
이 모양은 pandas 로 표를 만들 때 그대로 쓰입니다.
import pandas as pd
df = pd.DataFrame({"이름": ["푸름", "소담", "보람"], "점수": [90, 85, 70]})
print(df)
print(df["점수"].mean())
실행 결과
이름 점수
0 푸름 90
1 소담 85
2 보람 70
81.66666666666667
df["점수"] 처럼 열 이름으로 꺼내는 방식이 딕셔너리의 키와 같은 생각입니다.
7. 튜플
튜플은 리스트처럼 값을 순서대로 담지만, 한 번 만들면 바꿀 수 없습니다. 소괄호 ( ) 로 만듭니다.
point = (3, 5)
print(point[0], point[1], len(point))
실행 결과
3 5 2
point = (3, 5)
point[0] = 10
실행 결과
TypeError: 'tuple' object does not support item assignment
바꿀 수 없으니 좌표, 날짜처럼 한 묶음으로 고정된 값에 씁니다.
괄호 없이도 튜플
쉼표로 나열하면 괄호가 없어도 튜플입니다. 사실 지금까지 이미 많이 써 왔습니다.
t = 3, 5
print(t, type(t))
x, y = t # 튜플을 풀어서 담기
print(x, y)
실행 결과
(3, 5) <class 'tuple'>
3 5
x, y = 3, 5: 오른쪽이 튜플, 그것을 풀어 담기x, y = y, x: 오른쪽에 튜플을 만들었다가 풀어 담기. 그래서 한 줄로 값이 바뀜
함수에서 여러 값 돌려주기
return a, b 는 튜플 하나를 돌려주는 것입니다.
def share(a, b):
return a // b, a % b
result = share(17, 5)
print(result)
q, r = share(17, 5)
print(q, r)
실행 결과
(3, 2)
3 2
튜플로 정렬하기
튜플끼리는 앞의 값부터 비교합니다. 앞이 같으면 다음 값을 비교합니다.
people = [(90, "푸름"), (95, "소담"), (90, "보람")]
people.sort()
print(people)
실행 결과
[(90, '보람'), (90, '푸름'), (95, '소담')]
점수가 높은 순서로 세우고 싶으면 점수에 마이너스를 붙여 넣습니다.
people = [(-90, "푸름"), (-95, "소담"), (-90, "보람")]
people.sort()
for s, name in people:
print(name, -s)
실행 결과
소담 95
보람 90
푸름 90
pandas 와 scikit-learn 에서 만나는 튜플
import pandas as pd
df = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
print(df.shape)
rows, cols = df.shape
print(rows, "행", cols, "열")
실행 결과
(3, 2)
3 행 2 열
df.shape 는 (행 수, 열 수) 튜플입니다. X_train, X_test, y_train, y_test = train_test_split(...) 처럼 여러 값을 한 번에 받는 것도 같은 원리입니다.
8. 리스트, 튜플, 딕셔너리 비교
| 리스트 | 튜플 | 딕셔너리 | |
|---|---|---|---|
| 모양 | [1, 2, 3] |
(1, 2, 3) |
{"a": 1, "b": 2} |
| 꺼내기 | 번호 [0] |
번호 [0] |
키 ["a"] |
| 바꾸기 | 가능 | 불가능 | 가능 |
| 쓰임 | 순서 있는 여러 값 | 고정된 묶음, 여러 값 돌려주기 | 이름으로 찾기, 개수 세기 |
정리
- 딕셔너리는
{키: 값}. 키로 꺼내고, 없는 키는in이나get으로 확인한다. 딕셔너리[키] = 값은 없으면 추가, 있으면 덮어쓰기.items()로 키와 값을 함께 꺼낸다.- 개수 세기:
count[a] = count.get(a, 0) + 1 - 튜플은 바꿀 수 없는 리스트.
a, b = ...로 풀어 담는다. - 튜플은 앞의 값부터 비교하므로 정렬 기준을 앞에 둔다.
확인 문제
d = {"a": 1, "b": 2}일 때d["c"] = 3다음d["a"] = 10을 실행하면 d 는 어떻게 되나요?d.get("z", 0)은 키 "z" 가 없을 때 무엇을 돌려주나요?t = (1, 2, 3)일 때t.append(4)를 하면 어떻게 되나요?
연습해 보기
확인 문제 정답
{"a": 10, "b": 2, "c": 3}: 없던 c 는 추가되고, 있던 a 는 덮어써집니다.0- 오류가 납니다. 튜플은 바꿀 수 없어서
append가 없습니다.
댓글 0
로그인하면 댓글을 쓸 수 있습니다.