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 |
int/float |
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)
よくあるユースケース
- Web API データ:外部 API を呼び出す際に JSON データを送受信
- 設定ファイル:設定を JSON 形式で保存——INI より柔軟
- データ永続化:プログラムデータを JSON ファイルとして保存——CSV より構造化されており(ネストをサポート)
- データ交換:異なる言語やシステム間でデータを転送
❓ よくある質問
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 を追加してください。📖 まとめ
json.dumps()Python→JSON 文字列。json.loads()JSON 文字列→Pythonjson.dump()Python→JSON ファイル。json.load()JSON ファイル→Pythonensure_ascii=Falseで非 ASCII 文字を保持。indent=2で出力フォーマット- JSON 型マッピング:
object→dict、array→list、number→int/float、null→None - カスタム型には
default直列化関数が必要
📝 練習問題
-
基本(難易度 ⭐):名前、年齢、3 つの趣味(リスト)を含む辞書を作成してください。
json.dumps()を使ってフォーマット済み JSON 文字列を出力します(文字を保持、インデント 2)。 -
中級(難易度 ⭐⭐):2 つの関数
save_contacts(contacts)とload_contacts()を書いてください。連絡先リスト(辞書のリスト)をcontacts.jsonに保存し、プログラム起動時に自動読み込みします。各連絡先は名前、電話番号、メールを持ちます。 -
上級(難易度 ⭐⭐⭐):JSON を使った「簡易データエクスポーター」を実装してください。学生スコアリスト
students = [{"name": "Zhang San", "scores": {"Chinese": 85, "Math": 92}}]が与えられたとき、以下を出力します:1)フォーマット済み JSON ファイル。2)圧縮(インデントなし)JSON 文字列。3)キーをソートした JSON 文字列(sort_keys=True)。



