Korean (한국어) translation by Dae-yeop Lee (you can also view the original English article)
이전 튜토리얼에서는 파이썬 딕셔너리에 대해 배웠고, 딕셔너리가 키
/값 쌍을 가진 순서가 없는 집합이라는 것을 확인했습니다. 여기서 키는 예를 들어 리스트에서의 위치와 반대되는 것으로서 항목에 접근하는 데 사용됩니다.
이번 빠른 팁에서는 두 개의 사전을 서로 연결(병합)하는 방법을 보여드리겠습니다.
update() 메서드
다음과 같은 두 개의 딕셔너리가 있다고 해봅시다.
1 |
dict1 = {'bookA': 1, 'bookB': 2, 'bookC': 3} |
2 |
dict2 = {'bookC': 2, 'bookD': 4, 'bookE': 5} |
어떻게 이 두 딕셔너리를 하나의 딕셔너리에 병합할 수 있을까요? 이와 관련해서 사용할 수 있는 함수는 update([other])
입니다. 파이썬 문서에는 다음과 같이 적혀 있습니다.
other의 키/값 쌍으로 딕셔너리를 업데이트하고 기존 키를 덮어씁니다. None
을 반환한다.
update()
는 다른 딕셔너리 객체나 키/값 쌍으로 구성된 이터러블(튜플이나 길이가 2 인 기타 이터러블)를 받는다. 키워드 인수가 지정되면 딕셔너리는 그러한 키/값 쌍으로 갱신된다:d.update(red=1, blue=2)
따라서 위의 두 딕셔너리를 병합하려면 다음과 같이 입력하면 됩니다.
dict2.update(dict1)
결과를 확인하기 위해 다음과 같은 문장을 입력했다고 해봅시다.
print dict2.update(dict1)
이 경우 None
이 출력됩니다! 그 이유는 update()
함수가 새 딕셔너리를 반환하지 않기 때문입니다. 딕셔너리를 연결한 결과를 얻으려면 다음을 입력합니다.
print dict2
이 경우 다음과 같은 결과가 출력됩니다.
{'bookA': 1, 'bookB': 2, 'bookC': 3, 'bookD': 4, 'bookE': 5}
그럼 다음과 같이 하면 어떨까요?
1 |
dict1.update(dict2) |
2 |
print dict1 |
이 경우 다음과 같은 결과가 출력됩니다.
{'bookA': 1, 'bookB': 2, 'bookC': 2, 'bookD': 4, 'bookE': 5}
첫 번째 경우인 dict2.update(dict1)
에서는 딕셔너리 dict2
를 dict1
의 키/값 쌍으로 갱신하고 기존 키를 덮어씁니다. 여기서 차이를 확인할 수 있는 키는 'bookC'
입니다. 이 경우 dict1
의 키/값 쌍으로 갱신하고 있기 때문에 3
이라는 값을 가질 것입니다. 후자의 경우인 dict1.update(dict2)
에서는 반대로 될 텐데, dict2
의 키/값 쌍으로 딕셔너리 dict1
을 갱신하기 때문입니다.
하지만 update()
를 사용해서 두 개의 딕셔너리를 병합하는 데는 문제가 있습니다. 문제는 원본 딕셔너리가 수정될 수 있다는 사실에 있습니다. 다시 말해 dict2.update(dict1)
와 같은 첫 번째 경우에는 dict2
의 원래 버전이 수정될 수 있으며, 후자의 경우인 dict1.update(dict2)
에서는 dict1
의 원래 버전이 수정될 수 있습니다. 즉, 업데이트해야 할 딕셔너리의 원본 버전을 유지하는 데 관심이 없다면 update()
를 사용해 두 개의 사전을 병합해도 된다는 것입니다. 여기서 의미하는 원래 버전이란 키의 값을 유지한다는 것입니다.
단일 표현식으로 두 개의 딕셔너리 병합하기
하나의 표현식에서 두 개의 딕셔너리를 병합하는 데 사용할 수있는 또 다른 방법은 다음과 같습니다.
print dict(dict2, **dict1)
이 문장의 출력 결과는 다음과 같습니다.
{'bookA': 1, 'bookB': 2, 'bookC': 3, 'bookD': 4, 'bookE': 5}
따라서 dict1
이 dict2
를 덮어씁니다. dict2
가 dict1
을 덮어쓰게 하려면 다음과 같이 입력합니다.
print dict(dict1, **dict2)
이 경우 출력 결과는 다음과 같습니다.
{'bookA': 1, 'bookB': 2, 'bookC': 2, 'bookD': 4, 'bookE': 5}
키/값 유지하기
키/값을 유지하는 이전 문제로 되돌아가서, 어떻게 해야 각 딕셔너리의 원본을 유지하면서 두 개의 딕셔너리를 병합할 수 있을까요?
이 문제의 해결 방법은 다음과 같습니다(출처: StackOverflow 스레드의 답변).
1 |
from itertools import chain |
2 |
from collections import defaultdict |
3 |
dict1 = {'bookA': 1, 'bookB': 2, 'bookC': 3} |
4 |
dict2 = {'bookC': 2, 'bookD': 4, 'bookE': 5} |
5 |
dict3 = defaultdict(list) |
6 |
for k, v in chain(dict1.items(), dict2.items()): |
7 |
dict3[k].append(v) |
8 |
|
9 |
for k, v in dict3.items(): |
10 |
print(k, v) |
이 경우 출력 결과는 다음과 같습니다.
1 |
('bookA', [1]) |
2 |
('bookB', [2]) |
3 |
('bookC', [3, 2]) |
4 |
('bookD', [4]) |
5 |
('bookE', [5]) |
이번 팁에서 알 수 있듯이 파이썬을 사용해 두 개의 딕셔너리를 병합하는 것은 매우 쉬우며, 각 딕셔너리에 동일한 키의 값을 유지하고 싶다면 방법이 조금 더 복잡해집니다.