딕셔너리 응용하기

Tasker_Jang·6일 전

1. 키-값 쌍 추가하기

딕셔너리에 키-값 쌍을 추가하는 메서드는 두 가지가 있습니다.

메서드기능키가 이미 있을 때
setdefault(키, 값)키-값 쌍 추가기존 값 유지
update(키=값)키-값 쌍 추가 또는 값 수정새 값으로 덮어씀

setdefault — 키가 없을 때만 추가

setdefault는 키가 없으면 추가하고, 이미 있으면 기존 값을 유지합니다. 기본값을 지정하지 않으면 None이 들어갑니다.

d = {"a": 1, "b": 2}

# 키가 없으면 추가
d.setdefault("c", 3)
print(d)  # {'a': 1, 'b': 2, 'c': 3}

# 키가 이미 있으면 기존 값 유지
d.setdefault("a", 999)
print(d)  # {'a': 1, 'b': 2, 'c': 3} ← 'a'는 여전히 1

# 기본값을 지정하지 않으면 None
d.setdefault("d")
print(d)  # {'a': 1, 'b': 2, 'c': 3, 'd': None}

update — 값 수정 또는 추가

update는 키가 있으면 값을 수정하고, 키가 없으면 새로 추가합니다. 여러 개를 한 번에 수정하는 것도 가능합니다.

d = {"a": 1, "b": 2}

# 키의 값 수정
d.update(a=10)
print(d)  # {'a': 10, 'b': 2}

# 여러 개를 한 번에 수정
d.update(a=100, b=200, c=300)
print(d)  # {'a': 100, 'b': 200, 'c': 300}

update는 다양한 형태의 인자를 받을 수 있습니다. 특히 키가 숫자일 때는 키=값 형태를 쓸 수 없으므로 딕셔너리나 리스트, 튜플을 넣어서 수정합니다.

d = {1: "one", 2: "two"}

# 딕셔너리를 넣어서 수정 (키가 숫자일 때)
d.update({1: "하나", 3: "셋"})
print(d)  # {1: '하나', 2: 'two', 3: '셋'}

# 리스트로 수정 (키-값 쌍의 리스트)
d.update([[2, "둘"]])
print(d)  # {1: '하나', 2: '둘', 3: '셋'}

# 튜플로도 가능
d.update([(3, "three")])
print(d)  # {1: '하나', 2: '둘', 3: 'three'}

2. 키-값 쌍 삭제하기

방법기능반환값
pop(키)특정 키-값 쌍 삭제삭제한 값 반환
del 딕셔너리[키]특정 키-값 쌍 삭제반환값 없음
clear()모든 키-값 쌍 삭제반환값 없음
d = {"a": 1, "b": 2, "c": 3}

# pop: 삭제 후 값 반환
value = d.pop("a")
print(value)  # 1
print(d)      # {'b': 2, 'c': 3}

# del: 단순 삭제
del d["b"]
print(d)  # {'c': 3}

# clear: 모든 키-값 쌍 삭제
d.clear()
print(d)  # {}

💡 pop에 두 번째 인자로 기본값을 지정하면, 키가 없을 때 에러 대신 기본값을 반환합니다: d.pop("x", 0)0


3. 값 가져오기

get — 안전한 값 조회

get(키)는 딕셔너리에서 특정 키의 값을 가져옵니다. 딕셔너리[키]와 비슷하지만, 키가 없을 때 에러가 발생하지 않는다는 차이가 있습니다.

d = {"a": 1, "b": 2}

# get: 키가 없으면 None 반환 (에러 없음)
print(d.get("a"))    # 1
print(d.get("x"))    # None
print(d.get("x", 0)) # 0 (기본값 지정 가능)

# 대괄호: 키가 없으면 KeyError 발생
# print(d["x"])  # KeyError: 'x'

items, keys, values — 전체 조회

딕셔너리는 키와 값을 가져오는 세 가지 메서드를 제공합니다.

메서드반환값
items()키-값 쌍을 모두 가져옴
keys()키를 모두 가져옴
values()값을 모두 가져옴
d = {"name": "홍길동", "age": 25, "city": "서울"}

print(d.items())   # dict_items([('name', '홍길동'), ('age', 25), ('city', '서울')])
print(d.keys())    # dict_keys(['name', 'age', 'city'])
print(d.values())  # dict_values(['홍길동', 25, '서울'])

4. 리스트(튜플)로 딕셔너리 만들기

dict.fromkeys에 키가 담긴 리스트를 넣으면 딕셔너리를 간편하게 생성할 수 있습니다.

# fromkeys로 딕셔너리 생성 (기본값 None)
keys = ["a", "b", "c"]
d = dict.fromkeys(keys)
print(d)  # {'a': None, 'b': None, 'c': None}

# 기본값 지정
d = dict.fromkeys(keys, 0)
print(d)  # {'a': 0, 'b': 0, 'c': 0}

5. 반복문으로 딕셔너리 순회하기

items()를 활용하면 키와 값을 동시에 가져올 수 있습니다.

# for문으로 키와 값을 함께 출력
d = {"name": "홍길동", "age": 25, "city": "서울"}

for key, value in d.items():
    print(f"{key}: {value}")
# name: 홍길동
# age: 25
# city: 서울

6. 딕셔너리 컴프리헨션

리스트와 마찬가지로 딕셔너리도 for 반복문과 if 조건문을 사용하여 생성할 수 있습니다.

# 기본 딕셔너리 컴프리헨션
squares = {x: x ** 2 for x in range(5)}
print(squares)  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# if 조건 추가: 짝수만 필터링
even_squares = {x: x ** 2 for x in range(10) if x % 2 == 0}
print(even_squares)  # {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}

반복 중 삭제 — 주의할 점

딕셔너리를 for 반복문으로 순회하면서 직접 키-값 쌍을 삭제하면 에러가 발생합니다. 딕셔너리의 크기가 반복 중에 바뀌기 때문입니다.

d = {"a": 1, "b": 2, "c": 3, "d": 4}

# ❌ 반복 중 직접 삭제 → RuntimeError
# for key in d:
#     if d[key] > 2:
#         del d[key]  # RuntimeError: dictionary changed size during iteration

이럴 때는 삭제할 키-값 쌍을 제외하고 새 딕셔너리를 만드는 방식을 사용합니다. 딕셔너리 컴프리헨션이 이 문제를 깔끔하게 해결해줍니다.

# ✅ 컴프리헨션으로 조건에 맞는 요소만 남기기
d = {"a": 1, "b": 2, "c": 3, "d": 4}
d = {key: value for key, value in d.items() if value <= 2}
print(d)  # {'a': 1, 'b': 2}

7. 중첩 딕셔너리

딕셔너리의 값 부분에 다시 딕셔너리가 들어갈 수 있습니다. 내부 딕셔너리에 접근하려면 [] 대괄호를 단계만큼 반복해서 붙이고 키를 지정합니다.

# 중첩 딕셔너리
students = {
    "student1": {"name": "홍길동", "score": 90},
    "student2": {"name": "김철수", "score": 85}
}

# 접근: 대괄호를 단계만큼 사용
print(students["student1"]["name"])   # 홍길동
print(students["student2"]["score"])  # 85

# 값 수정
students["student1"]["score"] = 95
print(students["student1"])  # {'name': '홍길동', 'score': 95}

8. 딕셔너리의 복사 — copy vs deepcopy

리스트와 마찬가지로, 딕셔너리에도 할당, 얕은 복사, 깊은 복사의 개념이 동일하게 적용됩니다.

import copy

# 얕은 복사: 중첩된 딕셔너리는 공유됨
original = {"a": {"x": 1}, "b": 2}
shallow = original.copy()

shallow["a"]["x"] = 999
print(original["a"]["x"])  # 999 ← 원본도 변경됨!

# 깊은 복사: 완전히 독립
original = {"a": {"x": 1}, "b": 2}
deep = copy.deepcopy(original)

deep["a"]["x"] = 999
print(original["a"]["x"])  # 1 ← 원본은 변경되지 않음
구분copy()copy.deepcopy()
최상위 딕셔너리독립독립
중첩된 딕셔너리원본과 공유완전히 독립
사용 시점단순 딕셔너리중첩 딕셔너리

profile
ML Engineer 🧠 | AI 모델 개발과 최적화 경험을 기록하며 성장하는 개발자 🚀 The light that burns twice as bright burns half as long ✨

0개의 댓글