閉じる

PythonでJSONを整形表示する方法 json.dumps(indent)

JSONの構造はネストが深くなるほど視認性が下がります。

Pythonではjson.dumpsのindentオプションを使うことで、スペースやタブでインデントを付けた整形表示が簡単に行えます。

本記事では、初心者の方でも段階を踏んで理解できるように、基本から実務での注意点まで丁寧に解説します。

JSON整形表示の基本(json.dumpsのindent)

PythonのjsonモジュールでJSONを整形表示

Python標準ライブラリのjsonモジュールは、辞書やリストをJSON文字列へ変換したり、逆にJSON文字列をPythonオブジェクトへ変換できます。

特にjson.dumps整形表示に便利で、indent引数を指定すると読みやすい出力になります。

Python
# Pythonのjsonモジュールを使って整形表示する基本例
import json

data = {
    "user": {"id": 123, "name": "Taro"},
    "items": [{"id": 1, "qty": 2}, {"id": 2, "qty": 5}],
    "paid": False
}

# indent=2で整形されたJSON文字列を作る
pretty = json.dumps(data, indent=2)

# 画面に表示する
print(pretty)
実行結果
{
  "user": {
    "id": 123,
    "name": "Taro"
  },
  "items": [
    {
      "id": 1,
      "qty": 2
    },
    {
      "id": 2,
      "qty": 5
    }
  ],
  "paid": false
}

dictをJSON文字列に整形変換する基本形

基本形は辞書やリストをjson.dumpsへ渡すだけです。

出力はPythonのstr型になりますので、そのままprintで表示したり、ファイルに書き込めます。

Python
import json

order = {"id": 1001, "total": 2980, "currency": "JPY"}
json_text = json.dumps(order, indent=4)  # 4スペースで整形

print(type(json_text))  # 返り値の型を確認
print(json_text)
実行結果
<class 'str'>
{
    "id": 1001,
    "total": 2980,
    "currency": "JPY"
}

json.dumpsとは

json.dumps(obj, *, indent=None, ensure_ascii=True, sort_keys=False, separators=None, ...)は、PythonオブジェクトをJSON文字列へ変換します。

indentensure_asciisort_keysなどのオプションを使うと、見た目やエンコードの挙動を細かく制御できます。

indentの役割と効果

indentは各階層で付与するインデントを指定します。

整数を渡すとその数だけスペースを使い、文字列を渡すとその文字列をインデントとして使います。

たとえばindent=2は階層ごとに2スペース、indent="\t"はタブで下げます。

ネストが深くなるほど、読みやすさが大きく変わります。

indent=2/4/タブの違い

一般的には2スペース4スペースがよく使われます。

タブはファイルビューアによって見え方が変わるため、チームでの合意がなければスペースを推奨します。

Python
import json

sample = {"a": {"b": {"c": [1, 2, 3]}}}

print("indent=2")
print(json.dumps(sample, indent=2))  # 2スペース
print("\nindent=4")
print(json.dumps(sample, indent=4))  # 4スペース
print("\nindent='\\t' (タブ)")
print(json.dumps(sample, indent="\t"))  # タブ
実行結果
indent=2
{
  "a": {
    "b": {
      "c": [
        1,
        2,
        3
      ]
    }
  }
}

indent=4
{
    "a": {
        "b": {
            "c": [
                1,
                2,
                3
            ]
        }
    }
}

indent='\t' (タブ)
{
	"a": {
		"b": {
			"c": [
				1,
				2,
				3
			]
		}
	}
}

次の表は違いの要点です。

設定見た目長所注意点
indent=2小さい字下げ行の折返しが減り、横幅を保ちやすい深いネストで若干詰まって見える場合あり
indent=4大きい字下げ階層がより明確で把握しやすいファイルサイズがやや増える
indent=”\t”タブ字下げ表示幅をビューア設定で調整可能ビューアによって幅が変わり見え方が不統一

printで整形JSONを表示

整形済みJSONは文字列なので、そのままprint関数に渡せます。

ログ出力でも同様ですが、大量データの頻繁な整形はパフォーマンスに影響するため、後述の注意点も参照してください。

Python
import json

config = {"debug": True, "version": "1.0.0"}
print(json.dumps(config, indent=2))  # すぐに画面表示
実行結果
{
  "debug": true,
  "version": "1.0.0"
}

日本語やキー順を整えるオプション

ensure_ascii=Falseで日本語をそのまま出力

デフォルトではensure_ascii=Trueのため、日本語はエスケープされたUnicodeとして出力されます。

ensure_ascii=Falseにすると、日本語をそのまま表示できます。

Python
import json

profile = {"name": "山田太郎", "city": "東京都"}

print("ensure_ascii=True (デフォルト)")
print(json.dumps(profile, indent=2))  # \u5c71\u7530 のように出力

print("\nensure_ascii=False")
print(json.dumps(profile, indent=2, ensure_ascii=False))  # 日本語のまま
実行結果
ensure_ascii=True (デフォルト)
{
  "name": "\u5c71\u7530\u592a\u90ce",
  "city": "\u6771\u4eac\u90fd"
}

ensure_ascii=False
{
  "name": "山田太郎",
  "city": "東京都"
}

日本語を扱う場合はensure_ascii=Falseを基本にし、ファイルへ保存する際はUTF-8エンコーディングを指定すると安全です。

sort_keys=Trueでキーを並べ替え

sort_keys=Trueで、辞書のキーをアルファベット順に整列して出力します。

設定ファイルを比較するときや、毎回同じ順序で出力したい場合に有用です。

Python
import json

person = {"age": 30, "name": "Taro", "id": 100}

print("sort_keys=False")
print(json.dumps(person, indent=2, sort_keys=False))

print("\nsort_keys=True")
print(json.dumps(person, indent=2, sort_keys=True))
実行結果
sort_keys=False
{
  "age": 30,
  "name": "Taro",
  "id": 100
}

sort_keys=True
{
  "age": 30,
  "id": 100,
  "name": "Taro"
}

separatorsで余計なスペースを調整

separators区切り文字の直後につくスペースを制御します。

デフォルトは(",", ": ")です。

インデントしつつ、行内のスペースだけ減らすことも可能です。

Python
import json

data = {"a": 1, "b": [1, 2]}

print("デフォルト separators")
print(json.dumps(data, indent=2))  # ":" の後にスペースあり

print("\nseparators=(',', ':') でスペース削減")
print(json.dumps(data, indent=2, separators=(",", ":")))  # ":" の後のスペースなし
実行結果
デフォルト separators
{
  "a": 1,
  "b": [
    1,
    2
  ]
}

separators=(',', ':') でスペース削減
{
  "a":1,
  "b":[
    1,
    2
  ]
}

可読性を重視するならデフォルトのままサイズを少しでも減らしたいならseparators=(",", ":")が目安です。

よくある使い方と落とし穴

深いJSONを読みやすくする(indentの選び方)

ネストが深いJSONでは行あたりの情報量を抑えることが読みやすさにつながります。

一般にindent=2は横幅を保ちやすく、indent=4は階層が明確になります。

横長の値が多い場合は2、配列やオブジェクトが深く重なる場合は4を試すとよいです。

Python
import json

deep = {"a": {"b": {"c": {"d": {"e": [1, {"x": "y"}, 3]}}}}}

print("indent=2")
print(json.dumps(deep, indent=2))

print("\nindent=4")
print(json.dumps(deep, indent=4))
実行結果
indent=2
{
  "a": {
    "b": {
      "c": {
        "d": {
          "e": [
            1,
            {
              "x": "y"
            },
            3
          ]
        }
      }
    }
  }
}

indent=4
{
    "a": {
        "b": {
            "c": {
                "d": {
                    "e": [
                        1,
                        {
                            "x": "y"
                        },
                        3
                    ]
                }
            }
        }
    }
}

json.dumpsとjson.dumpの違い(画面表示/ファイル保存)

json.dumps文字列を返す関数、json.dumpファイルオブジェクトに直接書き込む関数です。

ファイル保存時はテキストモードとエンコーディングを忘れずに指定します。

Python
# ファイルに保存: json.dump
import json
from pathlib import Path

data = {"title": "レポート", "ok": True}

# UTF-8で保存し、日本語を可読のままにする
out = Path("output.json")
with out.open("w", encoding="utf-8") as f:
    json.dump(data, f, indent=2, ensure_ascii=False, sort_keys=True)

# 保存内容を読み戻して確認
with out.open("r", encoding="utf-8") as f:
    text = f.read()
    print(text)
実行結果
{
  "ok": true,
  "title": "レポート"
}

返り値はstrである点とエンコードの注意

json.dumpsの返り値はstrです。

バイト列として扱いたい場合は.encode("utf-8")で明示的にエンコードします。

ファイルに書き込むときはopen(..., encoding="utf-8")のようにエンコーディングを指定してください。

Python
import json

obj = {"msg": "こんにちは"}
txt = json.dumps(obj, ensure_ascii=False)  # 文字列
bin_data = txt.encode("utf-8")            # バイト列に変換

print(type(txt), len(txt))
print(type(bin_data), len(bin_data))
実行結果
<class 'str'> 16
<class 'bytes'> 26

文字数とバイト数は一致しない場合があるため、ネットワーク送信やサイズ見積りの際はバイト列で評価しましょう。

大きなJSONのパフォーマンス注意点

pretty printは開発用(本番はコンパクトに)

整形出力は読みやすさのための余白を大量に追加します。

本番のAPIレスポンスや大規模ログでは非推奨で、サイズと速度を優先するコンパクトな出力にすべきです。

具体的にはindent=Noneかつseparators=(",", ":")のように設定します。

Python
import json

big = {"items": [{"i": i, "v": [i, i*i, str(i)]} for i in range(1000)]}

# 本番想定: コンパクトな出力
compact = json.dumps(big, separators=(",", ":"), ensure_ascii=False)

# 開発向け: 読みやすい整形
pretty = json.dumps(big, indent=2, ensure_ascii=False)

print("compact length:", len(compact))
print("pretty  length:", len(pretty))
実行結果
compact length: 32218
pretty  length: 92226

インデントによるサイズ増加と速度への影響

インデントは改行とスペースを大量に追加します。

ネストが深いほどサイズ増加率が高くなり、生成時間も増加します。

以下はインデント幅ごとのサイズ比較です。

Python
import json

data = {"a": [{"b": {"c": list(range(50))}} for _ in range(50)]}

raw = json.dumps(data)  # デフォルト
i2  = json.dumps(data, indent=2)
i4  = json.dumps(data, indent=4)

print("no indent:", len(raw))
print("indent=2 :", len(i2),  " (+", round((len(i2)-len(raw))/len(raw)*100, 1), "%)")
print("indent=4 :", len(i4),  " (+", round((len(i4)-len(raw))/len(raw)*100, 1), "%)")
実行結果
no indent: 10307
indent=2 : 37415  (+ 263.0 %)
indent=4 : 64219  (+ 523.1 %)

整形は開発時のデバッグや一時的なログに限定し、配布や通信では極力コンパクトにするのが原則です。

まとめ

JSONの整形表示はjson.dumpsのindentで簡単に行え、2や4スペース、タブの使い分けで読みやすさを調整できます。

日本語はensure_ascii=Falseで可読に保ち、sort_keys=Trueseparatorsで順序やスペースを調整すると実務で扱いやすくなります。

なお返り値はstrで、ファイル保存時はencoding="utf-8"と組み合わせるのが安全です。

最後に、整形はサイズと速度を犠牲にする点を忘れず、本番ではコンパクトな出力を選ぶ方針を徹底してください。

この記事を書いた人
エーテリア編集部
エーテリア編集部

人気のPythonを初めて学ぶ方向けに、文法の基本から小さな自動化まで、実際に手を動かして理解できる記事を書いています。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!