閉じる

Pythonの辞書やリストをJSON化 json.dumpとjson.loadを解説

JSONはWeb APIや設定ファイルで広く使われるデータ形式です。

Pythonには標準でjsonモジュールがあり、辞書やリストを簡単に保存・読み込みできます。

本記事ではjson.dump/json.loadとjson.dumps/json.loadsの基本から、日本語の扱い、整形、よくあるエラーまでを、Python初心者の方に向けて丁寧に解説します。

JSONとPythonのjsonモジュールの基本

Pythonの辞書・リストはJSONにそのまま対応

Pythonのdict(辞書)やlist(リスト)は、JSONのobjectarrayにそのまま対応します。

つまり、普段のPythonのデータ構造をほぼそのままJSONに書き出し、また読み戻せます

まずは最小の例を見てみましょう。

Python
# Pythonの辞書をJSON文字列に変換して表示する例
import json

data = {
    "title": "入門",
    "tags": ["python", "json"],
    "published": True,
    "count": 3
}

# ensure_ascii=False で日本語をそのまま出力、indent=2 で見やすく整形
json_str = json.dumps(data, ensure_ascii=False, indent=2)
print(json_str)
実行結果
{
  "title": "入門",
  "tags": [
    "python",
    "json"
  ],
  "published": true,
  "count": 3
}

上の例では、PythonのTrueがJSONのtrueに、整数3が3に変換されています。

JSONではブール値が小文字(true/false)、nullはnullになる点に注意してください。

Pythonの型とJSONの対応

Pythonの基本的な型は、JSONの基本型に素直に写像されます

対応関係を表にまとめます。

Pythonの値/型JSONの型備考
dictobject{“a”: 1}キーは原則文字列(JSON仕様)
listarray[1, 2, 3]可変長の順序付き
tuplearray[1, 2]JSONではリスト扱い(後述)
strstring“hello”文字列はダブルクォート
int/floatnumber42, 3.14整数・実数ともnumber
boolbooleantrue/false小文字で表記
Nonenullnullそのままnull
その他(例: set, bytes)非対応直接は変換不可

非対応の型はそのままでは保存できません。

まずは辞書・リスト・文字列・数値・ブール・Noneの基本6種を使うのが安全です。

動作確認を簡単に行ってみましょう。

Python
# JSONが数値・bool・nullをどう扱うかを確認
import json

data = {"ok": True, "nothing": None, "pi": 3.14}
s = json.dumps(data)        # 文字列化
print(s)                    # JSON文字列

obj = json.loads(s)         # Pythonオブジェクトへ戻す
print(type(obj["ok"]), obj["ok"])
print(type(obj["nothing"]), obj["nothing"])
print(type(obj["pi"]), obj["pi"])
実行結果
{"ok": true, "nothing": null, "pi": 3.14}
<class 'bool'> True
<class 'NoneType'> None
<class 'float'> 3.14

JSONにコメントは不可

JSONにはコメントを書けません

よくあるミスとして// コメント/* ... */を入れてしまうケースがありますが、これはjson.loadsでもjson.loadでもJSONDecodeErrorになります。

Python
# コメント付きJSONはエラーになる例
import json

json_text = """
{
  "name": "Taro", // ここはコメント(エラー)
  "age": 20
}
"""

try:
    json.loads(json_text)
except json.JSONDecodeError as e:
    print("JSONDecodeError:", e)
実行結果
JSONDecodeError: Expecting property name enclosed in double quotes: line 3 column 19 (char 21)

メモを書きたい場合は別ファイルに書くか、専用のキー(例: “_comment”)を自分で定めて文字列として入れるなどの工夫をしましょう。

ファイルに書く・読む json.dumpとjson.load

ファイルに保存するにはjson.dump、ファイルから読み込むにはjson.loadを使います。

dump/loadは「ファイルオブジェクト」相手、dumps/loadsは「文字列」相手という対応を覚えると混乱しません。

辞書やリストをJSONファイルに保存する

with open(..., "w", encoding="utf-8")でファイルを開き、json.dumpにファイルオブジェクトを渡します。

日本語を崩さず保存するためensure_ascii=Falseを付けるのがポイントです。

Python
# users.json に辞書(リストを含む)を保存する
import json

users = {
    "users": [
        {"id": 1, "name": "山田太郎"},
        {"id": 2, "name": "Jane Doe"}
    ],
    "active": True
}

# UTF-8で書き込み、ensure_ascii=Falseで日本語をそのまま保存
with open("users.json", "w", encoding="utf-8") as f:
    json.dump(users, f, ensure_ascii=False, indent=2)

print("書き込み完了: users.json")
実行結果
書き込み完了: users.json

JSONファイルからPythonのデータに戻す

先ほど保存したusers.jsonを読み込み、辞書として扱えることを確かめます。

Python
# users.json を読み込んで中身と型を確認
import json

with open("users.json", "r", encoding="utf-8") as f:
    loaded = json.load(f)

print(type(loaded))         # dictになる
print(loaded["users"][0])   # 最初のユーザー
print("active =", loaded["active"])
実行結果
<class 'dict'>
{'id': 1, 'name': '山田太郎'}
active = True

読み込んだ瞬間から通常のPythonの辞書/リストとして扱えるので、キーアクセスやループ、条件分岐などがそのままできます。

日本語を正しく保存する

json.dumps/json.dumpは既定でensure_ascii=Trueです。

これだと日本語が\u3053のようなエスケープシーケンスになります。

ファイルとして人間が読める形にしたいときはensure_ascii=Falseを指定します。

Python
# ensure_ascii の違いを比較
import json

data = {"text": "こんにちは", "emoji": "🍣"}

s_default = json.dumps(data)  # 既定(ensure_ascii=True)
s_utf8 = json.dumps(data, ensure_ascii=False)

print("default:", s_default)
print("utf8   :", s_utf8)
実行結果
default: {"text": "\u3053\u3093\u306b\u3061\u306f", "emoji": "\ud83c\udf63"}
utf8   : {"text": "こんにちは", "emoji": "🍣"}

整形して見やすくする

読みやすいJSONにしたい場合はindentでインデント幅、sort_keys=Trueでキーをアルファベット順に整列できます。

開発中は整形、配布時は圧縮と使い分けると便利です。

Python
# 整形(Pretty Print)と圧縮(Minify)の例
import json

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

pretty = json.dumps(data, ensure_ascii=False, indent=2, sort_keys=True)
compact = json.dumps(data, ensure_ascii=False, separators=(",", ":"))

print("Pretty:\n", pretty)
print("Compact:", compact)
実行結果
Pretty:
 {
  "a": [
    3,
    2,
    1
  ],
  "z": 1
}
Compact: {"z":1,"a":[3,2,1]}

文字化けを防ぐUTF-8の指定

Windowsなどでは既定のテキストエンコーディングがUTF-8でない場合があります。

常にopen(..., encoding="utf-8")を明示し、書き出し時はensure_ascii=Falseを併用しましょう。

Python
# UTF-8で書いてUTF-8で読む(文字化け対策の基本形)
import json

data = {"title": "文字化け対策", "note": "UTF-8で統一しましょう。"}

with open("utf8.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

with open("utf8.json", "r", encoding="utf-8") as f:
    loaded = json.load(f)

print("OK:", loaded)
実行結果
OK: {'title': '文字化け対策', 'note': 'UTF-8で統一しましょう。'}

エディタ側のファイル保存エンコーディングもUTF-8に統一しておくとより安全です。

文字列で扱う json.dumpsとjson.loads

ファイルを使わずにJSON化して確認

ちょっと中身を見たい、といった場面ではjson.dumpsで文字列化してprintするのが手軽です。

Python
# dumps で文字列化して型と中身を確認
import json

data = [{"id": 1}, {"id": 2}]
s = json.dumps(data, indent=2)
print(type(s), "\n", s)
実行結果
<class 'str'> 
 [
  {
    "id": 1
  },
  {
    "id": 2
  }
]

JSON文字列から辞書やリストに戻す

APIから受け取ったJSON文字列をjson.loadsでPythonのデータに変換します。

loadsのsはstringのsと覚えると区別しやすいです。

Python
# JSON文字列をPythonオブジェクトへ
import json

json_text = '{"a": 1, "flags": [true, false], "nothing": null}'
obj = json.loads(json_text)

print(type(obj), obj)               # dict
print(type(obj["flags"]), obj["flags"])  # list
print(type(obj["nothing"]), obj["nothing"])  # NoneType/None
実行結果
<class 'dict'> {'a': 1, 'flags': [True, False], 'nothing': None}
<class 'list'> [True, False]
<class 'NoneType'> None

PythonでJSONを扱う注意点とコツ

dumpとdumps、loadとloadsの違い

dump/loadはファイル、dumps/loadsは文字列の相手です。

名前の末尾のsが付く方が「string」と覚えてください。

  • json.dump(obj, fp, ...): objをJSONとしてファイルオブジェクトfpに書く
  • json.load(fp): ファイルオブジェクトfpからJSONを読みobjにする
  • json.dumps(obj, ...): objをJSON文字列にする
  • json.loads(s): JSON文字列sをobjにする
Python
# 4関数の最小例で違いを確認
import json

# ファイルに書く: dump
with open("tmp.json", "w", encoding="utf-8") as f:
    json.dump({"x": 1}, f)

# 文字列を作る: dumps
s = json.dumps({"x": 1})
print("dumps ->", type(s), s)

# ファイルから読む: load
with open("tmp.json", "r", encoding="utf-8") as f:
    obj1 = json.load(f)

# 文字列から読む: loads
obj2 = json.loads('{"x": 1}')

print("load  ->", type(obj1), obj1)
print("loads ->", type(obj2), obj2)
実行結果
dumps -> <class 'str'> {"x": 1}
load  -> <class 'dict'> {'x': 1}
loads -> <class 'dict'> {'x': 1}

末尾カンマやコメントはエラーになる

JSONはJavaScriptに似ていますが別仕様です。

配列やオブジェクトの末尾カンマ、コメントはエラーです。

Python
# 末尾カンマのエラー例
import json

bad = '{"a": 1,}'   # "1," の後ろのカンマが余計
try:
    json.loads(bad)
except json.JSONDecodeError as e:
    print("JSONDecodeError:", e)
実行結果
JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 9 (char 8)

コメントに関しては前述の章の通り///* */も不可です。

JSONは「厳密に書く」ことが成功の近道です。

タプルはJSONではリストになる

JSONにタプル型はありません

PythonのtupleはJSONでは配列になり、読み戻すとlistになります。

必要ならtuple(...)で再変換してください。

Python
# タプルは配列として保存され、読み戻すとリストになる
import json

t = (1, 2, 3)
s = json.dumps(t)       # JSON文字列へ
back = json.loads(s)    # Pythonへ戻す

print(type(s), s)       # str と "[1, 2, 3]"
print(type(back), back) # list と [1, 2, 3]
実行結果
<class 'str'> [1, 2, 3]
<class 'list'> [1, 2, 3]

数値・bool・Noneは自動で対応する

整数・浮動小数・ブール値・Noneはそのまま保存/復元できます。

演算や比較は通常のPythonの値として扱えます

Python
# 数値・bool・None の往復確認
import json

data = {"i": 1, "f": 2.5, "flag": False, "nothing": None}
s = json.dumps(data)
obj = json.loads(s)

print(type(obj["i"]).__name__, obj["i"])
print(type(obj["f"]).__name__, obj["f"])
print(type(obj["flag"]).__name__, obj["flag"])
print(type(obj["nothing"]).__name__, obj["nothing"])
実行結果
int 1
float 2.5
bool False
NoneType None

浮動小数点は丸め誤差の影響を受ける場合があるため、厳密性が必要な金額などでは文字列にするなどの別対策も検討してください。

まとめ

ここまででjson.dump/json.load(ファイル)とjson.dumps/json.loads(文字列)の使い分け日本語を崩さないensure_ascii=Falseencoding="utf-8"の指定整形(indentsort_keys)、そして末尾カンマ・コメント禁止やタプルがリストになるといった注意点を確認しました。

まずは辞書とリストで小さく始め、文字列で結果を確認しながら、問題なければファイルに保存する、という流れで練習してみてください。

JSONは「シンプルに、厳密に」がコツです。

慣れてくるとAPI連携や設定の管理がぐっと楽になります。

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

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

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

URLをコピーしました!