Python에서 JSON의 중복 키를 딕셔너리 변환 전에 막는 방법
요약
Python에서 JSON 데이터를 딕셔너리로 로드할 때 발생하는 중복 키 문제를 다루고 있습니다. 기본 `json.loads()` 함수는 나중에 등장한 값만 남기므로, 원래의 모든 값을 추적하기 어렵습니다. 이를 해결하기 위해 `object_pairs_hook`을 사용하여 딕셔너리 변환 전의 (키, 값) 쌍 리스트를 순회하며 중복 키 발생 시 예외를 발생시키는 방법을 제시합니다.
핵심 포인트
- 기본 json.loads()는 중복 키가 있을 경우 마지막 값만 남깁니다.
- 중복 키 추적을 위해서는 object_pairs_hook 사용이 필수입니다.
- object_pairs_hook은 딕셔너리 변환 전의 (키, 값) 쌍 리스트를 순서대로 제공합니다.
- 커스텀 로직 구현 시 중첩된 구조에서도 재귀 처리가 필요 없습니다.
두 번 작성한 limit이 로드된 후에는 하나로 줄어들었다. Python의 json.loads()로 {"limit": 1, "limit": 100}을 읽으면, 남는 것은 100이다.
LLM의 출력을 도구(tool)의 인수로 전달할 경우, 중복 키를 딕셔너리 변환 전에 막고 싶다. 사라진 값은 나중에 추적할 수 없기 때문이다.
나는 strict=True도 시도해 봤지만, 같은 결과로 막혔다. 이름에서 기대했던 엄격함과 체크 범위가 달랐다.
CPython 3.14.8 표준 라이브러리로 실행했다. 입력은 손으로 작성한 검증용 JSON이다.
import json
raw = '{"limit": 1, "limit": 100}'
print('default:', json.loads(raw))
...
default: {'limit': 100}
strict: {'limit': 100}
object_hook: {'limit': 100}
정수인지 확인해도, 100은 통과한다. 원래의 중복은 딕셔너리에서 복원할 수 없다.
표준 라이브러리의 소스도 읽어봤다. Python 버전의 JSONObject()는 키와 값 쌍(pair)을 모으고, 보통은 dict(pairs)로 변환한다. 같은 키의 나중 값이 남고, 이어서 object_hook을 호출한다.
strict이 제어하는 것은 문자열 내의 제어 문자를 허용할지 여부이다. 같은 파일의 JSONDecoder 설명에서도 확인했다. 중복 키 거부는 포함되어 있지 않다. 이름이 혼란스럽다.
object_pairs_hook에는 딕셔너리 변환 전의 쌍들이 순서대로 전달된다. 중복을 발견하면 예외를 발생시킨다.
def unique_object(pairs):
result = {}
for key, value in pairs:
...
계속 실행한 결과.
normal OK {'limit': 1}
same_value NG duplicate key: 'limit'
nested NG duplicate key: 'limit'
...
같은 값의 중복도 거부한다.
중첩된 args에도 후크(hook)가 호출된다. 자체적인 재귀 처리는 필요 없다. 이스케이프는 먼저 해석되므로, limit과 \u006cimit도 같은 키로 감지할 수 있었다.
배열의 다른 요소에 있는 limit은 통과한다. result는 객체마다 새로 만든다.
흐름은
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기