Skip to main content

딕셔너리 (Dictionary)

학습 목표

  • 딕셔너리의 키-값(Key-Value) 구조를 이해한다
  • 딕셔너리 생성, 접근, 수정, 삭제를 수행할 수 있다
  • 다양한 순회(Iteration) 방법을 활용할 수 있다
  • 중첩 딕셔너리를 다룰 수 있다

왜 중요한가

딕셔너리는 키(Key)로 값(Value)에 빠르게 접근할 수 있는 매핑(Mapping) 자료구조입니다. O(1) 시간 복잡도로 검색이 가능하여 대량의 데이터에서도 효율적입니다. ML/DL에서 하이퍼파라미터 관리, 모델 설정, JSON 데이터 처리 등 핵심적인 역할을 합니다.

딕셔너리 생성

# 중괄호로 생성
student = {"name": "김철수", "age": 25, "score": 92}

# dict() 생성자
student = dict(name="김철수", age=25, score=92)

# 리스트로부터 생성
pairs = [("name", "김철수"), ("age", 25)]
student = dict(pairs)

# zip으로 생성
keys = ["name", "age", "score"]
values = ["김철수", 25, 92]
student = dict(zip(keys, values))

# 빈 딕셔너리
empty = {}
empty = dict()

# fromkeys - 동일한 기본값으로 생성
defaults = dict.fromkeys(["a", "b", "c"], 0)
print(defaults)  # {"a": 0, "b": 0, "c": 0}

접근과 수정

값 접근

student = {"name": "김철수", "age": 25, "score": 92}

# 대괄호 접근 (키가 없으면 KeyError)
print(student["name"])    # "김철수"
# print(student["email"])  # KeyError!

# get() 메서드 (키가 없으면 기본값 반환)
print(student.get("name"))         # "김철수"
print(student.get("email"))        # None
print(student.get("email", "없음"))  # "없음" (기본값 지정)

값 수정과 추가

student = {"name": "김철수", "age": 25}

# 수정
student["age"] = 26

# 추가 (새 키)
student["email"] = "kim@example.com"

# update() - 여러 키-값 한 번에
student.update({"score": 95, "grade": "A"})
student.update(city="서울")  # 키워드 인자도 가능

print(student)
# {"name": "김철수", "age": 26, "email": "kim@example.com", "score": 95, "grade": "A", "city": "서울"}

# setdefault - 키가 없을 때만 추가
student.setdefault("name", "이영희")    # 이미 있으므로 변경 없음
student.setdefault("phone", "010-1234")  # 없으므로 추가

삭제

student = {"name": "김철수", "age": 25, "score": 92}

# del 키워드
del student["score"]

# pop() - 삭제하면서 값 반환
age = student.pop("age")
print(age)  # 25

# pop() with default - KeyError 방지
email = student.pop("email", None)
print(email)  # None

# popitem() - 마지막 항목 삭제 (Python 3.7+)
last = student.popitem()
print(last)  # ("name", "김철수")

# clear() - 전체 삭제
student.clear()

순회 (Iteration)

config = {"lr": 0.001, "batch_size": 32, "epochs": 100}

# 키 순회 (기본)
for key in config:
    print(key, config[key])

# keys(), values(), items()
for key in config.keys():
    print(key)

for value in config.values():
    print(value)

for key, value in config.items():
    print(f"{key}: {value}")

# 출력:
# lr: 0.001
# batch_size: 32
# epochs: 100

딕셔너리 주요 메서드 요약

메서드설명반환값
d[key]키로 접근값 (없으면 KeyError)
d.get(key, default)안전한 접근값 또는 기본값
d[key] = value추가/수정-
d.update(other)일괄 업데이트None
d.pop(key, default)삭제 후 반환
d.setdefault(key, default)없을 때만 추가기존/새 값
key in d키 존재 확인bool
len(d)항목 수int

병합 (Python 3.9+)

defaults = {"color": "red", "size": "medium"}
custom = {"size": "large", "weight": "bold"}

# | 연산자 (새 딕셔너리 생성)
merged = defaults | custom
print(merged)  # {"color": "red", "size": "large", "weight": "bold"}

# |= 연산자 (in-place 병합)
defaults |= custom
print(defaults)  # {"color": "red", "size": "large", "weight": "bold"}

중첩 딕셔너리

# 중첩 딕셔너리
school = {
    "class_a": {
        "teacher": "김교사",
        "students": ["학생1", "학생2", "학생3"],
        "average_score": 85.5
    },
    "class_b": {
        "teacher": "이교사",
        "students": ["학생4", "학생5"],
        "average_score": 90.2
    }
}

# 접근
print(school["class_a"]["teacher"])           # "김교사"
print(school["class_a"]["students"][0])       # "학생1"
print(school["class_b"]["average_score"])     # 90.2

# 안전한 중첩 접근
teacher = school.get("class_c", {}).get("teacher", "미정")
print(teacher)  # "미정"

AI/ML에서의 활용

# 하이퍼파라미터 관리
hyperparams = {
    "model": "bert-base-uncased",
    "learning_rate": 3e-5,
    "batch_size": 16,
    "max_epochs": 10,
    "warmup_steps": 100,
    "weight_decay": 0.01,
}

# 실험 결과 기록
results = {
    "train_loss": [0.5, 0.3, 0.2],
    "val_loss": [0.6, 0.4, 0.35],
    "metrics": {
        "accuracy": 0.92,
        "f1_score": 0.89,
        "precision": 0.91,
        "recall": 0.87
    }
}

# 모델 체크포인트 저장 (PyTorch 스타일)
checkpoint = {
    "epoch": 10,
    "model_state_dict": "...",  # 실제로는 텐서 딕셔너리
    "optimizer_state_dict": "...",
    "loss": 0.2,
}

# JSON 응답 처리
api_response = {
    "status": "success",
    "data": {
        "predictions": [0.85, 0.12, 0.03],
        "labels": ["고양이", "개", "새"]
    }
}
top_label = api_response["data"]["labels"][0]
해시 가능한(Hashable) 불변 타입만 키로 사용할 수 있습니다. str, int, float, bool, tuple은 가능하고, list, dict, set은 불가합니다.
Python 3.7부터 딕셔너리는 삽입 순서를 보장합니다. Python 3.6에서는 CPython 구현에서만 보장되었고, 3.7부터 언어 사양으로 공식화되었습니다.
collections.defaultdict는 존재하지 않는 키에 접근할 때 자동으로 기본값을 생성하는 딕셔너리입니다. collections 문서에서 자세히 다룹니다.

체크리스트

  • 딕셔너리 생성, 접근, 수정, 삭제를 수행할 수 있다
  • get()[] 접근의 차이를 설명할 수 있다
  • keys(), values(), items()로 순회할 수 있다
  • 중첩 딕셔너리를 안전하게 접근할 수 있다

다음 문서