키-값 쌍으로 데이터를 저장하는 딕셔너리를 배워봅시다! 실무에서 JSON 데이터 처리, 설정 관리, 데이터베이스 레코드 표현 등에 필수적으로 사용됩니다. (25분 완독 ⭐⭐)
🎯 오늘의 학습 목표
📚 사전 지식
🎯 학습 목표 1: 딕셔너리가 무엇인지 이해하기
한 줄 설명
딕셔너리 = 키(Key)로 값(Value)을 찾는 자료구조
마치 사전처럼 단어(키)로 뜻(값)을 찾듯이, 키로 값을 찾습니다.
실생활 비유
1
2
3
4
5
6
7
8
9
| 📕 영어사전:
"apple" → "사과"
"banana" → "바나나"
"grape" → "포도"
👤 학생 정보:
"이름" → "홍길동"
"나이" → 25
"학과" → "컴퓨터공학"
|
리스트 vs 딕셔너리
1
2
3
4
5
6
7
8
9
10
11
12
13
| # 리스트 (인덱스로 접근)
student = ["홍길동", 25, "컴퓨터공학"]
print(student[0]) # 홍길동
print(student[1]) # 25 (뭘 의미하는지 불명확!)
# 딕셔너리 (키로 접근)
student = {
"name": "홍길동",
"age": 25,
"major": "컴퓨터공학"
}
print(student["name"]) # 홍길동
print(student["age"]) # 25 (의미가 명확!)
|
🎯 학습 목표 2: 딕셔너리 만들고 사용하기
기본 문법
1
2
3
4
5
6
7
8
9
10
11
12
| # 빈 딕셔너리
empty_dict = {}
# 또는
empty_dict = dict()
# 데이터가 있는 딕셔너리
person = {
"name": "홍길동",
"age": 25,
"city": "서울"
}
|
다양한 타입의 값
1
2
3
4
5
6
7
| student = {
"name": "홍길동", # 문자열
"age": 25, # 정수
"height": 175.5, # 실수
"married": False, # 불린
"hobbies": ["독서", "운동"] # 리스트
}
|
값 가져오기
1
2
3
4
5
6
7
8
9
10
| person = {
"name": "홍길동",
"age": 25,
"city": "서울"
}
# 키로 값 가져오기
print(person["name"]) # 홍길동
print(person["age"]) # 25
print(person["city"]) # 서울
|
값 변경 및 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| person = {
"name": "홍길동",
"age": 25
}
# 나이 변경
person["age"] = 26
# 새로운 항목 추가
person["city"] = "서울"
person["job"] = "개발자"
print(person)
# {'name': '홍길동', 'age': 26, 'city': '서울', 'job': '개발자'}
|
🎯 학습 목표 3: 딕셔너리 메서드 익히기
get() 메서드 (안전한 방법)
1
2
3
4
5
6
7
8
9
10
11
| person = {
"name": "홍길동",
"age": 25
}
# ❌ 없는 키 접근 - 에러 발생!
# print(person["phone"]) # KeyError!
# ✅ get() 사용 - 안전
print(person.get("phone")) # None
print(person.get("phone", "없음")) # 없음 (기본값)
|
keys(), values(), items()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| person = {
"name": "홍길동",
"age": 25,
"city": "서울"
}
# 모든 키
keys = person.keys()
print(list(keys)) # ['name', 'age', 'city']
# 모든 값
values = person.values()
print(list(values)) # ['홍길동', 25, '서울']
# 키-값 쌍
items = person.items()
print(list(items))
# [('name', '홍길동'), ('age', 25), ('city', '서울')]
|
값 삭제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| person = {
"name": "홍길동",
"age": 25,
"city": "서울"
}
# del로 삭제
del person["city"]
print(person) # {'name': '홍길동', 'age': 25}
# pop()으로 삭제하고 값 가져오기
age = person.pop("age")
print(age) # 25
print(person) # {'name': '홍길동'}
|
update() - 여러 항목 추가/수정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| person = {
"name": "홍길동",
"age": 25
}
# 여러 항목 한 번에 추가
person.update({
"city": "서울",
"job": "개발자",
"age": 26 # 기존 값 수정
})
print(person)
# {'name': '홍길동', 'age': 26, 'city': '서울', 'job': '개발자'}
|
🎯 학습 목표 4: 딕셔너리 순회와 반복 익히기
키만 반복
1
2
3
4
5
6
7
8
9
10
11
12
13
| scores = {
"국어": 85,
"영어": 92,
"수학": 78
}
# 방법 1: 키만 직접 반복
for subject in scores:
print(subject)
# 방법 2: keys() 명시
for subject in scores.keys():
print(subject)
|
키-값 함께 반복
1
2
3
4
5
6
7
8
9
| scores = {
"국어": 85,
"영어": 92,
"수학": 78
}
# items()로 키-값 함께 반복
for subject, score in scores.items():
print(f"{subject}: {score}점")
|
출력:
1
2
3
| 국어: 85점
영어: 92점
수학: 78점
|
값만 반복
1
2
3
4
5
6
7
8
9
| scores = {
"국어": 85,
"영어": 92,
"수학": 78
}
# values()로 값만 반복
for score in scores.values():
print(f"{score}점")
|
in 연산자
1
2
3
4
5
6
7
8
9
10
11
| person = {
"name": "홍길동",
"age": 25
}
# 키가 있는지 확인
if "name" in person:
print("이름이 있습니다")
if "phone" not in person:
print("전화번호가 없습니다")
|
🎯 학습 목표 5: 딕셔너리 고급 활용 패턴
패턴 1: 카운팅
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| text = "hello world"
count = {}
for char in text:
if char in count:
count[char] += 1
else:
count[char] = 1
print(count)
# {'h': 1, 'e': 1, 'l': 3, 'o': 2, ' ': 1, 'w': 1, 'r': 1, 'd': 1}
# 또는 get() 사용
text = "hello world"
count = {}
for char in text:
count[char] = count.get(char, 0) + 1
|
패턴 2: 그룹화
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| students = [
{"name": "홍길동", "grade": "A"},
{"name": "김철수", "grade": "B"},
{"name": "이영희", "grade": "A"},
{"name": "박민수", "grade": "B"}
]
# 학점별로 그룹화
groups = {}
for student in students:
grade = student["grade"]
name = student["name"]
if grade not in groups:
groups[grade] = []
groups[grade].append(name)
print(groups)
# {'A': ['홍길동', '이영희'], 'B': ['김철수', '박민수']}
|
패턴 3: 중첩 딕셔너리
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| config = {
"debug": True,
"max_connections": 100,
"timeout": 30,
"database": {
"host": "localhost",
"port": 5432,
"name": "mydb"
}
}
# 중첩 딕셔너리 접근
print(config["database"]["host"]) # localhost
# 안전하게 접근
db = config.get("database", {})
host = db.get("host", "unknown")
print(host) # localhost
|
🎯 학습 목표 6: 실전에서 딕셔너리 활용하기
예제 1: 학생 정보 관리
1
2
3
4
5
6
7
8
9
10
11
12
13
| student = {
"name": "홍길동",
"student_id": "2024001",
"grade": 3,
"major": "컴퓨터공학",
"gpa": 3.8
}
print(f"이름: {student['name']}")
print(f"학번: {student['student_id']}")
print(f"학년: {student['grade']}학년")
print(f"전공: {student['major']}")
print(f"학점: {student['gpa']}")
|
예제 2: 점수 통계
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| scores = {
"국어": 85,
"영어": 92,
"수학": 78,
"과학": 88
}
# 총점과 평균
total = sum(scores.values())
average = total / len(scores)
print(f"총점: {total}점")
print(f"평균: {average:.1f}점")
# 최고점과 최저점
max_score = max(scores.values())
min_score = min(scores.values())
print(f"최고점: {max_score}점")
print(f"최저점: {min_score}점")
|
예제 3: 상품 재고 관리
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| inventory = {
"사과": {"price": 1000, "stock": 50},
"바나나": {"price": 1500, "stock": 30},
"포도": {"price": 3000, "stock": 20}
}
# 1. 전체 상품 출력
for name, info in inventory.items():
print(f"{name}: {info['price']}원, 재고 {info['stock']}개")
# 2. 상품 판매 (재고 감소)
item = "사과"
quantity = 5
if item in inventory:
if inventory[item]["stock"] >= quantity:
inventory[item]["stock"] -= quantity
total = inventory[item]["price"] * quantity
print(f"{item} {quantity}개 판매 완료. 금액: {total}원")
else:
print("재고 부족")
|
💡 실전 팁 & 주의사항
💡 Tip 1: 키는 변경 불가능한 타입만
1
2
3
4
5
6
7
8
9
10
11
| # ✅ 가능한 키 타입
dict1 = {
"name": "홍길동", # 문자열
1: "one", # 숫자
(1, 2): "tuple" # 튜플
}
# ❌ 불가능한 키 타입
# dict2 = {
# [1, 2]: "list" # 리스트는 키로 사용 불가!
# }
|
💡 Tip 2: get()으로 안전하게 접근
1
2
3
4
5
6
7
| person = {"name": "홍길동"}
# ❌ KeyError 위험
# age = person["age"] # 에러!
# ✅ 안전한 방법
age = person.get("age", 0) # 없으면 0 반환
|
💡 Tip 3: in으로 키 존재 확인
1
2
3
4
5
6
7
| person = {"name": "홍길동", "age": 25}
# 키 존재 확인 후 접근
if "phone" in person:
print(person["phone"])
else:
print("전화번호 없음")
|
💡 Tip 4: 순서 유지 (Python 3.7+)
1
2
3
4
5
6
7
8
9
| # Python 3.7 이상에서는 입력 순서 유지
person = {
"name": "홍길동",
"age": 25,
"city": "서울"
}
print(person)
# 입력한 순서대로 출력됨
|
💡 Tip 5: 중복 키는 마지막 값 유지
1
2
3
4
5
6
7
8
| # 중복된 키는 마지막 값으로 덮어씀
person = {
"name": "홍길동",
"age": 25,
"name": "김철수" # 덮어씀!
}
print(person) # {'name': '김철수', 'age': 25}
|
💡 Tip 6: update()로 딕셔너리 병합
1
2
3
4
5
6
7
8
9
| dict1 = {"a": 1, "b": 2}
dict2 = {"c": 3, "d": 4}
# update()로 병합
dict1.update(dict2)
print(dict1) # {'a': 1, 'b': 2, 'c': 3, 'd': 4}
# Python 3.9+ 병합 연산자
# dict3 = dict1 | dict2
|
🧪 연습 문제
문제 1: 학생 성적 관리 시스템
과제: 학생들의 과목별 성적을 딕셔너리로 관리하고 다양한 통계를 출력하세요.
초기 데이터:
1
2
3
4
5
| students = {
"홍길동": {"국어": 85, "영어": 90, "수학": 78},
"김철수": {"국어": 92, "영어": 88, "수학": 95},
"이영희": {"국어": 78, "영어": 85, "수학": 82}
}
|
요구사항:
- 각 학생의 총점과 평균을 계산하여 출력하세요
- 전체 학생 중 평균이 가장 높은 학생을 찾아 출력하세요
- 각 과목의 반 평균 점수를 계산하여 출력하세요
- 새로운 학생 “박민수”의 성적(국어: 88, 영어: 92, 수학: 85)을 추가하세요
- 추가 후 전체 학생 정보를 다시 출력하세요
💡 힌트
values()로 점수 리스트 추출 sum()과 len()으로 평균 계산 max() 함수와 lambda로 최대값 찾기 - 중첩 딕셔너리 순회:
for name, scores in students.items()
✅ 정답
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| students = {
"홍길동": {"국어": 85, "영어": 90, "수학": 78},
"김철수": {"국어": 92, "영어": 88, "수학": 95},
"이영희": {"국어": 78, "영어": 85, "수학": 82}
}
# 1. 각 학생의 총점과 평균
print("=== 학생별 성적 ===")
student_averages = {}
for name, scores in students.items():
total = sum(scores.values())
average = total / len(scores)
student_averages[name] = average
print(f"{name}: 총점 {total}점, 평균 {average:.1f}점")
# 2. 평균이 가장 높은 학생
top_student = max(student_averages, key=student_averages.get)
print(f"\n최우수 학생: {top_student} ({student_averages[top_student]:.1f}점)")
# 3. 과목별 반 평균
print("\n=== 과목별 반 평균 ===")
subjects = ["국어", "영어", "수학"]
for subject in subjects:
scores = [student[subject] for student in students.values()]
average = sum(scores) / len(scores)
print(f"{subject}: {average:.1f}점")
# 4. 새로운 학생 추가
students["박민수"] = {"국어": 88, "영어": 92, "수학": 85}
# 5. 전체 학생 정보 출력
print("\n=== 전체 학생 정보 ===")
for name, scores in students.items():
total = sum(scores.values())
average = total / len(scores)
print(f"{name}: {scores} (평균: {average:.1f}점)")
|
출력:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| === 학생별 성적 ===
홍길동: 총점 253점, 평균 84.3점
김철수: 총점 275점, 평균 91.7점
이영희: 총점 245점, 평균 81.7점
최우수 학생: 김철수 (91.7점)
=== 과목별 반 평균 ===
국어: 85.0점
영어: 87.7점
수학: 85.0점
=== 전체 학생 정보 ===
홍길동: {'국어': 85, '영어': 90, '수학': 78} (평균: 84.3점)
김철수: {'국어': 92, '영어': 88, '수학': 95} (평균: 91.7점)
이영희: {'국어': 78, '영어': 85, '수학': 82} (평균: 81.7점)
박민수: {'국어': 88, '영어': 92, '수학': 85} (평균: 88.3점)
|
문제 2: 텍스트 분석 시스템
과제: 문장에서 단어의 빈도수를 분석하고 통계를 출력하세요.
초기 데이터:
1
| text = "python is powerful python is easy python is fun coding with python is amazing"
|
요구사항:
- 문장을 단어로 분리하여 각 단어의 빈도수를 딕셔너리로 저장하세요
- 빈도수가 2회 이상인 단어만 필터링하여 출력하세요
- 빈도수가 가장 높은 단어를 찾아 출력하세요
- 전체 단어 수(중복 포함)와 고유 단어 수를 출력하세요
- 모든 단어를 빈도수 기준으로 내림차순 정렬하여 출력하세요
💡 힌트
split()으로 단어 분리 get(key, 0)으로 안전하게 카운팅 items() 순회로 조건 필터링 max() 함수로 최대 빈도수 찾기 sorted() 함수와 key=lambda로 정렬
✅ 정답
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| text = "python is powerful python is easy python is fun coding with python is amazing"
# 1. 단어 빈도수 계산
words = text.split()
frequency = {}
for word in words:
frequency[word] = frequency.get(word, 0) + 1
print("=== 전체 단어 빈도수 ===")
for word, count in frequency.items():
print(f"{word}: {count}번")
# 2. 빈도수 2회 이상 단어 필터링
print("\n=== 빈도수 2회 이상 단어 ===")
frequent_words = {word: count for word, count in frequency.items() if count >= 2}
for word, count in frequent_words.items():
print(f"{word}: {count}번")
# 3. 최다 빈도 단어
most_common_word = max(frequency, key=frequency.get)
print(f"\n최다 빈도 단어: '{most_common_word}' ({frequency[most_common_word]}번)")
# 4. 통계 정보
total_words = len(words)
unique_words = len(frequency)
print(f"\n전체 단어 수: {total_words}개")
print(f"고유 단어 수: {unique_words}개")
# 5. 빈도수 기준 내림차순 정렬
print("\n=== 빈도수 순위 ===")
sorted_frequency = sorted(frequency.items(), key=lambda x: x[1], reverse=True)
for i, (word, count) in enumerate(sorted_frequency, 1):
print(f"{i}위: {word} ({count}번)")
|
출력:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| === 전체 단어 빈도수 ===
python: 4번
is: 4번
powerful: 1번
easy: 1번
fun: 1번
coding: 1번
with: 1번
amazing: 1번
=== 빈도수 2회 이상 단어 ===
python: 4번
is: 4번
최다 빈도 단어: 'python' (4번)
전체 단어 수: 13개
고유 단어 수: 8개
=== 빈도수 순위 ===
1위: python (4번)
2위: is (4번)
3위: powerful (1번)
4위: easy (1번)
5위: fun (1번)
6위: coding (1번)
7위: with (1번)
8위: amazing (1번)
|
🎯 연습 문제 핵심 포인트
- 딕셔너리 CRUD: 추가(
dict[key] = value), 조회(dict.get(key)), 수정, 삭제 패턴 이해 - 중첩 딕셔너리: 학생별 과목 성적 같은 2차원 데이터 관리
- 딕셔너리 순회:
items(), keys(), values() 메서드 활용 - 통계 계산:
sum(), len(), max() 함수로 데이터 분석 - 데이터 정렬:
sorted() 함수와 key 매개변수로 딕셔너리 정렬 - 안전한 접근:
get(key, default)로 KeyError 방지
📝 오늘 배운 내용 정리
- 딕셔너리: 키-값 쌍으로 데이터 저장
- 생성:
{} 또는 dict() - 접근:
dict[key] 또는 dict.get(key) - 수정: 직접 할당 또는
update() - 삭제:
del 또는 pop() - 순회:
keys(), values(), items() - 활용: 카운팅, 그룹화, 중첩 구조
🔗 관련 자료
📚 이전 학습
Day 11: 튜플 다루기 (tuple) ⭐⭐
어제는 수정 불가능한 데이터 타입인 튜플을 배웠습니다!
📚 다음 학습
Day 13: 세트 다루기 (set) ⭐⭐
내일은 중복을 허용하지 않는 세트(집합) 자료구조를 배웁니다!
“늦었다고 생각할 때가 가장 빠른 시기입니다!” 🚀
| Day 12/100 | Phase 2: 자료형 마스터하기 | #100DaysOfPython |