HOWTO · Python

Python에서 사전을 문자열로 변환

이 튜토리얼은 Python에서 사전을 문자열로 또는 그 반대로 변환하는 방법을 보여줍니다.

이 페이지의 내용

사전은 화면 표시, 로그 기록, 데이터 교환을 위해 문자열로 만들 수 있지만, 용도마다 적합한 형식은 다릅니다. str()는 Python 표현을 만들고, json.dumps()는 데이터 교환에 사용할 JSON 텍스트를 생성하며, pprint.pformat()는 읽기 쉬운 형식으로 출력합니다. 반복문을 사용하면 표시 형식을 직접 정할 수도 있습니다. 결과는 모두 문자열이지만, 자료형을 보존하거나 원래 사전을 다시 복원할 수 있다고 모두 보장하는 것은 아닙니다.

사전을 문자열로 변환하는 적절한 방법 선택하기

디버깅 메시지처럼 Python에 맞는 간단한 표현이 필요하다면 str()를 사용하세요. 다른 시스템이 JSON을 요구하고 값이 JSON에서 지원하는 자료형에 해당한다면 json.dumps()를 사용하세요. 중첩된 Python 데이터를 더 쉽게 살펴보려면 pprint.pformat()를 선택하세요. name: Alice, score: 9처럼 출력 형식을 직접 정해야 한다면 사용자 지정 문자열을 만드세요.

이 형식들은 서로 바꿔 쓸 수 있는 직렬화 형식이 아닙니다. 사용자 지정 표시 문자열이나 str()의 결과는 모호할 수 있어 다른 프로그램이 파싱하기에 적합하지 않을 수 있습니다. JSON은 객체, 배열, 문자열, 숫자, 불리언, null을 지원합니다. 튜플이나 집합처럼 Python에서만 사용하는 값은 변환하거나 다른 방법을 선택해야 합니다. pickle도 문자열 변환이 아닙니다. 직렬화 결과는 바이트이며, 신뢰할 수 없는 출처의 pickle 데이터를 불러오면 유해한 코드가 실행될 수 있습니다.

Python 표현을 위해 str() 사용하기

읽기 쉬운 Python 표현이면 충분할 때 str(dictionary)를 사용하면 간결합니다. 결과에는 사전을 나타내는 중괄호와 키 및 값의 Python식 표현이 포함됩니다. 이 형식은 다른 언어와 데이터를 주고받기 위한 약속이 아니라 Python용입니다. 예를 들어 Python은 True와 None을 사용하지만 JSON은 true와 null을 사용합니다.

다음 예제를 실행해 보세요.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

details = {"name": "Ada", "active": True}
text = str(details)
print(type(text).__name__)
print(text)
str
{'name': 'Ada', 'active': True}

사전을 dict라는 이름의 변수에 할당하지 마세요. Python의 내장 자료형 이름을 가리게 됩니다. 또한 객체를 텍스트로 변환한다고 해서 그 텍스트에서 원래 객체를 다시 복원할 수 있는 것은 아닙니다.

json.dumps()로 사전을 JSON 직렬화하기

표준 데이터 교환 문자열이 필요하다면 json.dumps()를 사용하세요. 이에 대응하는 json.loads() 함수는 JSON 텍스트를 파싱해 Python 값으로 변환합니다. JSON으로 왕복 변환하면 JSON과 호환되는 데이터는 보존되지만 모든 Python 자료형이 그대로 유지되지는 않습니다. 튜플은 배열이 되어 다시 불러오면 리스트가 되고, 사전 키는 JSON에서 지원하는 자료형이어야 합니다. 기본 설정에서는 ASCII가 아닌 문자가 이스케이프됩니다. 해당 문자를 그대로 표시하려면 ensure_ascii=False로 설정하세요. JSON을 읽기 쉽게 만들려면 indent를 사용하고, 용도에 맞는 경우 안정적인 키 순서를 위해 sort_keys=True를 지정할 수 있습니다.

다음 예제를 실행해 보세요.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

import json

record = {"name": "Ada", "score": 9}
text = json.dumps(record)
restored = json.loads(text)
print(text)
print(restored == record)
{"name": "Ada", "score": 9}
True

json.dumps()가 반환하는 값은 문자열입니다. 사전에 JSON으로 인코딩할 수 없는 값이 포함되어 있다면 변환 방법을 명시적으로 정하거나 해당 데이터를 위해 설계된 형식을 선택하세요. 모든 Python 객체를 JSON으로 처리할 수 있다고 가정하지 마세요.

읽기 쉬운 출력을 위해 pprint.pformat()로 사전 형식 지정하기

콘솔에 바로 출력하는 대신 서식이 적용된 문자열이 필요하다면 pprint.pformat()를 사용하세요. 긴 중첩 구조를 여러 줄로 나눌 수 있어 복잡한 데이터를 살펴볼 때 유용합니다. 결과는 JSON이 아니라 Python에 맞춘 표시용 표현입니다. 옵션으로 너비, 들여쓰기, 깊이, 간결성을 조정할 수 있습니다. 깊이 제한을 설정하면 중첩된 내용이 생략되므로 서식화된 결과에 모든 값이 표시되지 않을 수 있습니다.

다음 예제를 실행해 보세요.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

import pprint

record = {"user": {"name": "Ada", "roles": ["author", "editor"]}}
text = pprint.pformat(record, sort_dicts=False)
print(type(text).__name__)
print(text)
str
{'user': {'name': 'Ada', 'roles': ['author', 'editor']}}

반환된 문자열은 로그 메시지와 같이 필요한 곳에서 사용할 수 있습니다. 반면 pprint.pprint()는 서식이 적용된 텍스트를 스트림에 씁니다. 결과를 변수에 보관하지 않고 바로 출력하려는 경우에 유용합니다.

반복문으로 사용자 지정 문자열 만들기

사용자 지정 형식을 사용하면 구분자와 레이블을 직접 정할 수 있습니다. str.join()을 사용하는 컴프리헨션은 문자열을 반복해서 이어 붙이는 일을 피하고, 끝에 불필요한 구분자가 붙지 않도록 간단히 처리할 수 있습니다. 다른 프로그램이 결과를 파싱할 예정이라면 값에 선택한 구분자가 들어 있을 때 어떻게 처리할지 정하세요. 단순한 표시 형식은 이스케이프 규칙을 자동으로 제공하지 않습니다.

다음 예제를 실행해 보세요.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

scores = {"Ada": 9, "Lin": 8}
text = ", ".join(f"{name}: {score}" for name, score in scores.items())
print(text)
Ada: 9, Lin: 8

이 방법은 사람이 읽을 한 줄을 만드는 데 적합합니다. 결과를 교환하거나 나중에 파싱할 수 있도록 저장해야 한다면 JSON을 사용하거나, 따옴표와 이스케이프 규칙을 명확히 정의하고 구현한 형식을 사용하세요.

문자열을 다시 사전으로 변환하기

JSON 문자열은 json.loads()로 파싱하세요. 이 함수는 JSON 문법을 처리하며 str()가 만든 임의의 Python 출력은 처리하지 않습니다. 직접 제어하는 Python 리터럴 문자열이라면 ast.literal_eval()로 사전을 포함한 지원되는 리터럴 구조를 파싱할 수 있습니다. 이 함수는 임의의 Python 식을 평가하지는 않지만 일반적인 파서는 아닙니다. 신뢰할 수 없거나 크기가 매우 크거나 많은 리소스를 소모하는 입력에는 사용하지 마세요. 결과의 자료형과 내용이 애플리케이션의 요구 사항에 맞는지 확인하세요.

다음 예제를 실행해 보세요.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

import ast
import json

json_text = '{"name": "Ada", "score": 9}'
python_text = "{'name': 'Ada', 'score': 9}"
print(json.loads(json_text))
print(ast.literal_eval(python_text))
{'name': 'Ada', 'score': 9}
{'name': 'Ada', 'score': 9}

문자열을 만든 형식에 맞는 파서를 선택하세요. 해당 형식에 대응하는 파서와 명확히 정의된 규칙이 없다면, 어느 파서도 임의의 사용자 지정 표시 문자열에서 사전을 안정적으로 복원할 수 없습니다.