Python 딕셔너리 병합, 3.5+ 언패킹 연산자 활용

문제 상황

API 응답 데이터와 기본 설정값을 합쳐야 하는 상황이 자주 발생했다. update() 메서드를 쓰면 원본을 수정하게 되어 불편했다.

# 기존 방식
default_config = {'timeout': 30, 'retry': 3}
user_config = {'timeout': 60}

result = default_config.copy()
result.update(user_config)

매번 copy()를 호출하는 게 번거로웠다.

해결

Python 3.5부터 딕셔너리 언패킹 연산자(**)를 사용할 수 있다는 걸 알게 됐다.

default_config = {'timeout': 30, 'retry': 3}
user_config = {'timeout': 60}

result = {**default_config, **user_config}
# {'timeout': 60, 'retry': 3}

원본을 건드리지 않으면서 한 줄로 병합이 가능하다. 뒤에 오는 딕셔너리의 값이 우선순위를 가진다.

여러 개 병합

base = {'a': 1}
middle = {'b': 2}
last = {'c': 3}

merged = {**base, **middle, **last}
# {'a': 1, 'b': 2, 'c': 3}

주의사항

  • Python 3.5 미만에서는 SyntaxError 발생
  • 프로덕션 환경이 Python 2.7이라면 여전히 update() 방식을 써야 함
  • 중첩된 딕셔너리는 얕은 복사만 수행됨

팀 내부 서비스는 Python 3.6을 사용 중이라 바로 적용했다. 코드가 훨씬 간결해졌다.