개념 이해
딕셔너리 병합이란 두 개 이상의 딕셔너리를 하나의 딕셔너리로 합치는 것입니다.
dict1 = {"이름": "민수", "나이": 17}
dict2 = {"학교": "과학고", "학년": 2}
두 딕셔너리를 병합하면 다음과 같은 결과를 만들 수 있습니다.
{'이름': '민수', '나이': 17, '학교': '과학고', '학년': 2}
주의: 두 딕셔너리에 같은 키가 있으면 일반적으로 뒤에 오는 딕셔너리의 값으로 덮어쓰기 됩니다.
1. | 연산자로 병합하기
Python 3.9 이상에서 사용할 수 있는 가장 간단한 방법입니다.
dict1 = {"이름": "민수", "나이": 17}
dict2 = {"학교": "과학고", "학년": 2}
result = dict1 | dict2
print(result)
출력 결과
{'이름': '민수', '나이': 17, '학교': '과학고', '학년': 2}
원본 딕셔너리 dict1, dict2는 바뀌지 않고 새로운 딕셔너리가 만들어집니다.
2. update() 메서드로 병합하기
update()는 기존 딕셔너리에 다른 딕셔너리의 내용을 추가합니다.
dict1 = {"이름": "민수", "나이": 17}
dict2 = {"학교": "과학고", "학년": 2}
dict1.update(dict2)
print(dict1)
출력 결과
{'이름': '민수', '나이': 17, '학교': '과학고', '학년': 2}
update()는 dict1 자체를 직접 수정합니다. 원본을 보존해야 한다면 copy()를 함께 사용하는 것이 좋습니다.
3. ** 언패킹으로 병합하기
Python 3.5 이상에서 많이 사용하는 방법입니다.
dict1 = {"이름": "민수", "나이": 17}
dict2 = {"학교": "과학고", "학년": 2}
result = {**dict1, **dict2}
print(result)
출력 결과
{'이름': '민수', '나이': 17, '학교': '과학고', '학년': 2}
**dict1은 dict1의 내용을 펼쳐서 새 딕셔너리에 넣는다는 뜻입니다.
4. copy() + update()로 원본 보존하기
원본 dict1을 바꾸지 않고 병합하고 싶을 때 사용합니다.
dict1 = {"이름": "민수", "나이": 17}
dict2 = {"학교": "과학고", "학년": 2}
result = dict1.copy()
result.update(dict2)
print("dict1:", dict1)
print("result:", result)
출력 결과
dict1: {'이름': '민수', '나이': 17}
result: {'이름': '민수', '나이': 17, '학교': '과학고', '학년': 2}
dict1은 그대로 두고, result라는 새로운 딕셔너리에 병합 결과를 저장합니다.
5. for문으로 직접 병합하기
딕셔너리의 키와 값을 하나씩 꺼내서 직접 추가할 수 있습니다.
dict1 = {"이름": "민수", "나이": 17}
dict2 = {"학교": "과학고", "학년": 2}
result = {}
for key, value in dict1.items():
result[key] = value
for key, value in dict2.items():
result[key] = value
print(result)
출력 결과
{'이름': '민수', '나이': 17, '학교': '과학고', '학년': 2}
for문을 사용하면 중복 키를 어떻게 처리할지 직접 제어할 수 있습니다.
6. 여러 개의 딕셔너리를 반복문으로 병합하기
딕셔너리가 3개 이상일 때 유용합니다.
dict1 = {"이름": "민수"}
dict2 = {"나이": 17}
dict3 = {"학교": "과학고"}
dict4 = {"학년": 2}
dict_list = [dict1, dict2, dict3, dict4]
result = {}
for d in dict_list:
result.update(d)
print(result)
출력 결과
{'이름': '민수', '나이': 17, '학교': '과학고', '학년': 2}
병합할 딕셔너리 개수가 많을 때 코드가 깔끔해집니다.
7. 중복 키가 있을 때 값 더하기
같은 키가 있으면 덮어쓰지 않고 값을 더할 수 있습니다.
score1 = {"국어": 80, "수학": 90}
score2 = {"수학": 5, "영어": 85}
result = score1.copy()
for key, value in score2.items():
if key in result:
result[key] = result[key] + value
else:
result[key] = value
print(result)
출력 결과
{'국어': 80, '수학': 95, '영어': 85}
수학은 score1에 90, score2에 5가 있으므로 90 + 5 = 95가 됩니다.
8. 중복 키 값을 리스트로 묶기
같은 키의 값을 모두 보존하고 싶을 때 사용합니다.
dict1 = {"이름": "민수", "취미": "독서"}
dict2 = {"이름": "지아", "학교": "과학고"}
result = {}
for d in [dict1, dict2]:
for key, value in d.items():
if key in result:
result[key].append(value)
else:
result[key] = [value]
print(result)
출력 결과
{'이름': ['민수', '지아'], '취미': ['독서'], '학교': ['과학고']}
중복된 키의 값을 잃지 않고 모두 저장할 수 있습니다.
9. collections.ChainMap으로 병합처럼 사용하기
ChainMap은 여러 딕셔너리를 실제로 합치지 않고 연결해서 하나처럼 사용할 수 있게 합니다.
from collections import ChainMap
dict1 = {"이름": "민수", "나이": 17}
dict2 = {"학교": "과학고", "학년": 2}
merged = ChainMap(dict1, dict2)
print(merged["이름"])
print(merged["학교"])
print(dict(merged))
출력 결과
민수
과학고
{'학교': '과학고', '학년': 2, '이름': '민수', '나이': 17}
ChainMap은 원본 딕셔너리를 복사하지 않고 연결하므로, 설정값을 여러 단계로 관리할 때 유용합니다.
10. 딕셔너리 컴프리헨션으로 선택 병합하기
필요한 키만 골라서 병합할 수 있습니다.
dict1 = {"이름": "민수", "나이": 17}
dict2 = {"학교": "과학고", "비밀번호": "1234"}
merged = {**dict1, **dict2}
result = {
key: value
for key, value in merged.items()
if key != "비밀번호"
}
print(result)
출력 결과
{'이름': '민수', '나이': 17, '학교': '과학고'}
병합하면서 특정 키를 제외하거나 조건에 맞는 데이터만 남길 수 있습니다.
방법 비교표
| 방법 | 특징 | 원본 수정 여부 | 추천 상황 |
|---|---|---|---|
| | 연산자 | 가장 간단하고 직관적 | 수정 안 함 | Python 3.9 이상 |
| update() | 기존 딕셔너리에 추가 | 수정함 | 원본을 바꿔도 될 때 |
| {**dict1, **dict2} | 새 딕셔너리 생성 | 수정 안 함 | Python 3.5 이상 |
| copy() + update() | 원본 보존 | 수정 안 함 | 안전한 병합 |
| for문 | 세부 제어 가능 | 작성 방식에 따라 다름 | 중복 키 처리 규칙이 필요할 때 |
| ChainMap | 실제 병합 없이 연결 | 수정 안 함 | 설정값, 기본값 관리 |
확인 문제
문제 1. Python 3.9 이상에서 딕셔너리를 병합하는 간단한 연산자는?
① + ② | ③ & ④ *
정답: ② |
예: result = dict1 | dict2
예: result = dict1 | dict2
문제 2. update() 메서드는 원본 딕셔너리를 직접 수정한다. O / X
정답: O
dict1.update(dict2)를 실행하면 dict1의 내용이 바뀝니다.
dict1.update(dict2)를 실행하면 dict1의 내용이 바뀝니다.
문제 3. 다음 코드의 출력 결과는?
a = {"점수": 80}
b = {"점수": 95}
print(a | b)
정답: {'점수': 95}
중복 키가 있으면 뒤쪽 딕셔너리 b의 값으로 덮어쓰기 됩니다.
중복 키가 있으면 뒤쪽 딕셔너리 b의 값으로 덮어쓰기 됩니다.
문제 4. 여러 딕셔너리를 실제로 합치지 않고 연결해서 사용하는 도구는?
① zip ② ChainMap ③ range ④ split
정답: ② ChainMap
collections 모듈의 ChainMap을 사용합니다.
collections 모듈의 ChainMap을 사용합니다.