포스트

[Python 100일 챌린지] Day 12 - 딕셔너리 다루기 (dict)

[Python 100일 챌린지] Day 12 - 딕셔너리 다루기 (dict)

키-값 쌍으로 데이터를 저장하는 딕셔너리를 배워봅시다! 실무에서 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}
}

요구사항:

  1. 각 학생의 총점과 평균을 계산하여 출력하세요
  2. 전체 학생 중 평균이 가장 높은 학생을 찾아 출력하세요
  3. 각 과목의 반 평균 점수를 계산하여 출력하세요
  4. 새로운 학생 “박민수”의 성적(국어: 88, 영어: 92, 수학: 85)을 추가하세요
  5. 추가 후 전체 학생 정보를 다시 출력하세요
💡 힌트
  • 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"

요구사항:

  1. 문장을 단어로 분리하여 각 단어의 빈도수를 딕셔너리로 저장하세요
  2. 빈도수가 2회 이상인 단어만 필터링하여 출력하세요
  3. 빈도수가 가장 높은 단어를 찾아 출력하세요
  4. 전체 단어 수(중복 포함)와 고유 단어 수를 출력하세요
  5. 모든 단어를 빈도수 기준으로 내림차순 정렬하여 출력하세요
💡 힌트
  • 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번)

🎯 연습 문제 핵심 포인트

  1. 딕셔너리 CRUD: 추가(dict[key] = value), 조회(dict.get(key)), 수정, 삭제 패턴 이해
  2. 중첩 딕셔너리: 학생별 과목 성적 같은 2차원 데이터 관리
  3. 딕셔너리 순회: items(), keys(), values() 메서드 활용
  4. 통계 계산: sum(), len(), max() 함수로 데이터 분석
  5. 데이터 정렬: sorted() 함수와 key 매개변수로 딕셔너리 정렬
  6. 안전한 접근: get(key, default)로 KeyError 방지

📝 오늘 배운 내용 정리

  1. 딕셔너리: 키-값 쌍으로 데이터 저장
  2. 생성: {} 또는 dict()
  3. 접근: dict[key] 또는 dict.get(key)
  4. 수정: 직접 할당 또는 update()
  5. 삭제: del 또는 pop()
  6. 순회: keys(), values(), items()
  7. 활용: 카운팅, 그룹화, 중첩 구조

🔗 관련 자료


📚 이전 학습

Day 11: 튜플 다루기 (tuple) ⭐⭐

어제는 수정 불가능한 데이터 타입인 튜플을 배웠습니다!

📚 다음 학습

Day 13: 세트 다루기 (set) ⭐⭐

내일은 중복을 허용하지 않는 세트(집합) 자료구조를 배웁니다!


“늦었다고 생각할 때가 가장 빠른 시기입니다!” 🚀

Day 12/100 Phase 2: 자료형 마스터하기 #100DaysOfPython
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.