JSON データ処理

JSON(JavaScript Object Notation)は Web 上で最も一般的なデータ交換フォーマットです。ほとんどすべての Web API が JSON データを返します。Python の json モジュールを使うと、Python オブジェクトと JSON 文字列の間の変換が簡単に行えます。


1. Python オブジェクト <-> JSON 文字列

例:JSON 文字列への直列化

PYTHON
import json

# Python dict → JSON 文字列(直列化)
data = {
    "name": "Zhang San",
    "age": 25,
    "is_student": False,
    "scores": [85, 92, 78],
    "address": None
}

json_str = json.dumps(data, ensure_ascii=False, indent=2)
print(json_str)
▶ 試してみよう

出力:

JSON
{
  "name": "Zhang San",
  "age": 25,
  "is_student": false,
  "scores": [85, 92, 78],
  "address": null
}
💡 ensure_ascii=False は重要です: このパラメータがないと、非 ASCII 文字は Unicode コードにエスケープされます。元の文字を保持するために使用します。indent=2 は出力を見やすくフォーマットします。本番環境では、indent=None を使用して 1 行に圧縮し、帯域幅を節約します。


2. JSON 文字列 -> Python オブジェクト(逆直列化)

例:JSON 文字列の逆直列化

PYTHON
import json

json_str = '{"name": "Zhang San", "age": 25, "is_student": false, "scores": [85, 92, 78]}'

data = json.loads(json_str)
print(data)                             # {'name': 'Zhang San', 'age': 25, ...}
print(type(data))                       # <class 'dict'>
print(data["name"])                     # Zhang San
print(data["scores"][0])                # 85
▶ 試してみよう

JSON 型から Python 型へのマッピング

JSON Python
string str
number intfloat
boolean bool
null None
array list
object dict

3. JSON ファイル I/O

例:JSON ファイルの読み書き

PYTHON
import json

# JSON ファイルに書き込み
data = {
    "students": [
        {"name": "Zhang San", "age": 20, "score": 85},
        {"name": "Li Si", "age": 21, "score": 92},
        {"name": "Wang Wu", "age": 19, "score": 78}
    ]
}

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

# JSON ファイルを読み取り
with open("students.json", "r", encoding="utf-8") as f:
    loaded = json.load(f)

print(f"Number of students: {len(loaded['students'])}")
for s in loaded["students"]:
    print(f"  {s['name']}: {s['score']}")
▶ 試してみよう

例:データ永続化(難易度 ⭐⭐)

PYTHON
import json
import os

DATA_FILE = "notes.json"

def load_notes():
    """JSON ファイルからメモを読み込み"""
    if not os.path.exists(DATA_FILE):
        return []
    with open(DATA_FILE, "r", encoding="utf-8") as f:
        return json.load(f)

def save_notes(notes):
    """メモを JSON ファイルに保存"""
    with open(DATA_FILE, "w", encoding="utf-8") as f:
        json.dump(notes, f, ensure_ascii=False, indent=2)

def add_note(title, content):
    """メモを追加"""
    notes = load_notes()
    notes.append({"title": title, "content": content})
    save_notes(notes)
    print(f"Note added: {title}")

def list_notes():
    """すべてのメモを表示"""
    notes = load_notes()
    if not notes:
        print("No notes yet")
        return
    for i, note in enumerate(notes, 1):
        print(f"{i}. {note['title']}")

add_note("Learning Python", "Learned the JSON module today")
add_note("Shopping List", "Buy milk, bread, eggs")
list_notes()
▶ 試してみよう

4. 複雑なデータ型の処理

デフォルトでは、json モジュールは基本型のみをサポートします。カスタムオブジェクトは手動で変換する必要があります:

例:カスタム直列化

PYTHON
import json
from datetime import datetime

def custom_serializer(obj):
    """カスタム直列化 — datetime などの型を処理"""
    if isinstance(obj, datetime):
        return obj.strftime("%Y-%m-%d %H:%M:%S")
    raise TypeError(f"Cannot serialize {type(obj)}")

data = {
    "name": "Zhang San",
    "created_at": datetime.now(),
    "active": True
}

json_str = json.dumps(data, default=custom_serializer, ensure_ascii=False, indent=2)
print(json_str)
▶ 試してみよう

よくあるユースケース


❓ よくある質問

Q json.dumps()json.dump() の違いは何ですか?
A dumps() は JSON 文字列を返します(s は string)。dump() はファイルオブジェクトに直接書き込みます。同様に、loads() は文字列からパースし、load() はファイルオブジェクトから読み取ります。「s」サフィックスは string を示します。
Q JSON の CSV に対する利点は何ですか?
A JSON はネスト構造(リスト内の辞書、辞書内のリスト)をサポートしますが、CSV はフラットなテーブルしか表現できません。JSON はデータ型を自動的に保持します(数値、ブール値、null)。CSV の値はすべて文字列です。JSON はより読みやすいです。欠点は、JSON ファイルは通常 CSV より大きいことです。
Q ensure_ascii=False を設定しないとどうなりますか?
A 中国語の文字は \uXXXX 形式にエスケープされます。プログラムの機能には影響しません——json.loads() は自動的に復元します。ただし、人間の可読性の観点からは、エスケープされた内容は完全に読めません。JSON ファイルを手動で表示する必要がある場合は、ensure_ascii=False を追加してください。

📖 まとめ


📝 練習問題

  1. 基本(難易度 ⭐):名前、年齢、3 つの趣味(リスト)を含む辞書を作成してください。json.dumps() を使ってフォーマット済み JSON 文字列を出力します(文字を保持、インデント 2)。

  2. 中級(難易度 ⭐⭐):2 つの関数 save_contacts(contacts)load_contacts() を書いてください。連絡先リスト(辞書のリスト)を contacts.json に保存し、プログラム起動時に自動読み込みします。各連絡先は名前、電話番号、メールを持ちます。

  3. 上級(難易度 ⭐⭐⭐):JSON を使った「簡易データエクスポーター」を実装してください。学生スコアリスト students = [{"name": "Zhang San", "scores": {"Chinese": 85, "Math": 92}}] が与えられたとき、以下を出力します:1)フォーマット済み JSON ファイル。2)圧縮(インデントなし)JSON 文字列。3)キーをソートした JSON 文字列(sort_keys=True)。

100%