Python · dict · nested JSON
Python dict keys를 camelCase로 재귀 변환
중첩 dict/list에는 문자열 helper만으로 부족합니다. data boundary에서 재귀 변환하고 collision이 나면 실패시키세요.
dict/list key 재귀 변환
from typing import Any
def snake_to_camel(name: str) -> str:
parts = [part for part in name.split("_") if part]
if not parts: return name
head, *tail = parts
return head.lower() + "".join(part[:1].upper() + part[1:].lower() for part in tail)
def keys_to_camel(value: Any) -> Any:
if isinstance(value, list): return [keys_to_camel(item) for item in value]
if not isinstance(value, dict): return value
output: dict[Any, Any] = {}
for key, child in value.items():
next_key = snake_to_camel(key) if isinstance(key, str) else key
if next_key in output: raise ValueError(f"Key collision: {next_key}")
output[next_key] = keys_to_camel(child)
return outputlist를 먼저 처리하고 scalar는 그대로 반환하며 dict는 camelCase string key로 새로 구성합니다.
JSON parse 직후 converter 적용
import json
snake_payload = json.loads(raw_json)
camel_payload = keys_to_camel(snake_payload)
print(json.dumps(camel_payload, indent=2))json.loads가 일반 dict/list를 만들기 때문에 parse 직후를 명확하고 테스트 가능한 naming boundary로 사용할 수 있습니다.
필요하면 underscore/dollar prefix 보존
def snake_to_camel_preserving_prefix(name: str) -> str:
prefix_length = len(name) - len(name.lstrip("_$"))
prefix = name[:prefix_length]
body = name[prefix_length:]
return prefix + snake_to_camel(body)_id, __typename, $schema_version은 prefix를 분리한 뒤 나머지 이름만 변환합니다.
프로덕션 고려사항
- 반복 underscore와 빈 token을 정규화할지 보존할지 규칙을 정하세요.
- user_id / userId collision은 error를 발생시켜야 합니다.
- payload 일부만 변환한다면 제외 키나 stop path를 사용하세요.
- dataclass, ORM, model, serializer가 더 적합한 naming boundary일 수 있습니다.
JSON 경계 온라인 테스트
중첩 객체, 배열, 제외 키, stop path, 접두사, 충돌, key-only diff를 구현 전에 확인하세요.
.json 파일을 놓거나 기기에서 선택
파일은 브라우저에서만 읽습니다. 최대 크기: 5 MB.
변환된 JSON
{
"userProfile": {
"firstName": "Ada",
"createdAt": "2026-09-12"
}
}파싱, 파일 읽기, 포맷 및 키 변환은 모두 브라우저에서 로컬로 실행됩니다. JSON 입력은 변환 서버로 전송되지 않습니다.