◀ 3.

Pythonの辞書型(dict)を文字列(string)に変換する方法

Pythonの辞書を表示したいのか、JSONとして交換したいのかで方法を選びます。元の型まで復元できるかは別に確認します。

Python辞書の人向け表示とJSON交換、復元時の型の違いを分ける図

旧コード内の「# →」は説明用の表記です。print(s)は文字列の外側に引用符を付けて出力しません。REPLで文字列値を見る表現と、printで表示される文字を区別してください。

この記事の要点
  • Python で辞書 (dict) を文字列に変換する 4 つの方法
  • str(dict): 簡易、Pythonのオブジェクト表現。引用符や内容は値によって変わる
  • json.dumps(dict): 標準 JSON 形式(ダブルクォート、推奨)
  • repr(dict): str() とほぼ同じ、デバッグ用
  • pprint.pformat(dict): 整形表示(ネストが深いとき向き)

 

方法 1: str() (簡易・非推奨用途)

標準dictの内容を人が確認するための表現です。JSONとは異なり、値によって引用符・True/None・独自オブジェクト表現等を含みます。常に再読込できるdictリテラルとは限りません。

d = {'name': 'Alice', 'age': 30}
s = str(d)
print(s)
# → "{'name': 'Alice', 'age': 30}"
print(type(s))
# → <class 'str'>

注意: 出力はJSON生成の契約を満たしません。単純な数値等では偶然JSONとして読める場合もありますが、引用符の置換でJSONを作らずjson.dumpsで生成してください。

方法 2: json.dumps() (推奨)

他システムやファイル・API レスポンスで使うなら json.dumps() を使います。標準の JSON 形式(ダブルクォート)で出力されます。

import json

d = {"name": "Alice", "age": 30, "tags": ["dev", "admin"]}
s = json.dumps(d)
print(s)
# → '{"name": "Alice", "age": 30, "tags": ["dev", "admin"]}'

# 日本語を含む場合は ensure_ascii=False
d = {"名前": "アリス"}
s = json.dumps(d, ensure_ascii=False)
print(s)
# → '{"名前": "アリス"}'

# 整形して出力
s = json.dumps(d, ensure_ascii=False, indent=2)
print(s)
# → {
#     "名前": "アリス"
#   }

json.dumps の主要オプション

オプション効果
indent=22 スペースでインデント整形
ensure_ascii=False日本語等をASCII用のUnicodeエスケープへ変換せず出力。ファイルの文字コード設定とは別
sort_keys=Trueキーを比較してソート。混在型で比較不能ならTypeErrorになり得る
separators=(',', ':')区切り文字をカスタマイズ(最小化等)
default=str非対応の値を文字列化するが型は失われる。辞書キーの非対応型まで救済する設定ではない

方法 3: repr()

オブジェクトの表現を取得します。標準dictでは通常str()と同様の表現ですが、repr()も一般的なシリアライズ形式や安全な復元を保証しません。

d = {'name': 'Alice', 'age': 30}
print(repr(d))
# → "{'name': 'Alice', 'age': 30}"

方法 4: pprint.pformat() (整形)

ネストが深い辞書を可読性高く整形したい場合。

from pprint import pformat

d = {
    "users": [
        {"name": "Alice", "age": 30, "tags": ["dev", "admin"]},
        {"name": "Bob", "age": 25, "tags": ["dev"]}
    ]
}
print(pformat(d))
# → {'users': [{'age': 30, 'name': 'Alice', 'tags': ['dev', 'admin']},
#               {'age': 25, 'name': 'Bob', 'tags': ['dev']}]}

逆変換: 文字列を辞書に戻す

JSON 文字列 → dict

import json
s = '{"name": "Alice", "age": 30}'
d = json.loads(s)
print(d)
# → {'name': 'Alice', 'age': 30}

Pythonリテラル文字列を読む(strの一般的な逆ではない)

次の既知の小さいリテラルではast.literal_evalを使えますが、任意のstr/repr出力の復元器ではありません。コードを評価しないことと、無制限の入力を安全に処理できることは別で、悪意ある巨大/深い入力を渡しません。evalは使いません。

import ast
s = "{'name': 'Alice', 'age': 30}"
d = ast.literal_eval(s)
print(d)
# → {'name': 'Alice', 'age': 30}

# eval() でも動くが、任意コード実行リスクがあるので literal_eval を使う

使い分けまとめ

用途推奨
API / ファイル保存 / 他言語と連携json.dumps()
デバッグ・ログ出力str() or repr()
整形表示(人間が読む)pprint.pformat() or json.dumps(..., indent=2)
ネスト構造の可視化pprint.pformat()

注意点

  • json.dumps はすべての型に対応していない: datetime, set, bytes, カスタムクラスはそのままだとエラー。変換規則を設計してdefault/clsで実装。default=strは型を失うため、後で同じ型に戻す必要がある保存形式へ無条件に使わない
  • str()はJSON生成の代替ではない: 引用符だけでなくbool/None等も異なる。読める偶然の例を仕様と扱わない
  • 容量とメモリ: indentでサイズは増える。indentなしでもdumpsは文字列全体を作るため、巨大データへの万能対策ではない
  • 循環参照: 標準dictのstr/reprは再帰部分を{...}等で表す。json.dumpsは既定の循環検査でValueError。check_circular=Falseで回避しない

関連記事

JSONの往復で同じ型に戻るとは限らない

JSONのオブジェクトキーは文字列です。整数キーは文字列化され、1と文字列の1のようなキーが同居すると情報が曖昧になる場合があります。tupleは配列として出力され、loads後はlistです。datetime等をdefault=strで書くと元の型/時間帯の意味は自動では戻りません。保存形式にはキーの型・日時形式・欠落/NULLの意味も決めてください。

NaN/Infinityは標準JSONの数値ではありません。Pythonのdumpsは既定で出力できるため、標準準拠を確認する例ではallow_nan=Falseを指定します。これは整数キーの変換や日時等の独自型まで検証する設定ではありません。loadsでも受信サイズ・深さ・返る型を検査し、JSON文字列なら必ずdictとは思わず、必要ならisinstanceで確認します。

import json

data = {"name": "アリス", "enabled": True, "items": [1, None]}
text = json.dumps(data, ensure_ascii=False, allow_nan=False)
restored = json.loads(text)
assert restored == data

# JSON object keys are strings: numeric keys do not round-trip as numeric keys.
assert json.loads(json.dumps({1: "one"})) == {"1": "one"}

# A tuple becomes a JSON array and is decoded as a list.
assert json.loads(json.dumps({"point": (1, 2)})) == {"point": [1, 2]}

# A Python representation can mark a cycle; it is not necessarily a literal.
cycle = {}
cycle["self"] = cycle
assert "{...}" in str(cycle)
try:
    json.dumps(cycle)
except ValueError:
    pass
else:
    raise AssertionError("A JSON cycle must be rejected")

エラーが出たときの確認順

  1. TypeError:非対応型やキー型、sort_keysの比較対象を確認する。default=strですべてを黙って文字列化しない。
  2. ValueError:循環参照やallow_nan=False時の非有限数を確認する。循環検査を切るのではなくデータ構造を直す。
  3. JSONDecodeError:Python表現をloadsへ渡していないか、引用符・途中切れ・余分な文字を確認する。信頼できない入力をevalへ渡さない。

str/repr/pprintも秘密値を隠す機能ではありません。ログに全辞書を出さず、公開してよい項目だけ選びます。JSONをHTML/JavaScriptへ埋める際の文脈別エスケープは別問題で、ensure_ascii=False/Trueで安全を保証できません。

公式:json / literal_evalの制限 / pprint。追加例と境界条件はPython3.12で検査し、全独自クラスや他言語の実装を保証するものではありません。

子ページ

子ページはありません

同階層のページ
  1. 型の確認
  2. strからintへの型変換
  3. 辞書型を文字列に変換する方法

最近更新/作成されたページ