ToolDeck

PythonでCSVをJSONに変換する方法

·Backend Developer·レビュー担当Priya Sharma·公開日

無料の CSVからJSONへの変換ツール をブラウザで直接使用 — インストール不要。

CSVからJSONへの変換ツール をオンラインで試す →

CSVファイルはあらゆる場面で登場します — エクスポートされたレポート、データベースダンプ、ログの抽出など — そしていつかはPythonでそのCSVをJSONに変換する必要が生じます。 標準ライブラリは2つのモジュールでこれを処理します: csv.DictReader が各行をPythonのdictに変換し、 json.dumps() がそれらのdictをJSON文字列にシリアライズします。コードを書かずに素早く変換したい場合は、CSV to JSON コンバーターがブラウザ上で即座に処理します。このガイドでは完全なプログラム的手順を解説します: json.dump() vs json.dumps()、 JSONファイルへの書き込み、dataclassのシリアライズ、CSV値の型変換、 datetimeとDecimalの処理、そして orjson などの高性能な代替手段まで。 すべての例はPython 3.10+を対象としています。

  • csv.DictReaderはdictのリストを生成します — json.dump(rows, f, indent=2)でリスト全体をJSONファイルに書き込みます。
  • json.dump()はファイルオブジェクトに直接書き込みます。json.dumps()は文字列を返します。適切な方を選ぶことで不要なコピーを回避できます。
  • CSVの値は常に文字列です。JSONにシリアライズする前に、数値カラムをint()またはfloat()で明示的に変換してください。
  • ensure_ascii=Falseをjson.dumps()に渡すことで、Unicode文字(アクセント付き文字、CJKテキスト)を出力に保持できます。
  • CSVから取得したdatetime、UUID、Decimalには、カスタムのフォールバック関数とともにdefault=パラメータを使用します。
Before · json
After · json
order_id,product,quantity,price
ORD-7291,Wireless Keyboard,2,49.99
ORD-7292,USB-C Hub,1,34.50
[
  {
    "order_id": "ORD-7291",
    "product": "Wireless Keyboard",
    "quantity": "2",
    "price": "49.99"
  },
  {
    "order_id": "ORD-7292",
    "product": "USB-C Hub",
    "quantity": "1",
    "price": "34.50"
  }
]
注意:quantityとpriceがそのままの出力ではJSON文字列( "2" "49.99")として現れていることに注目してください。 CSVには型システムがありません — すべての値は文字列です。 この問題の修正方法は後述の型変換セクションで説明します。

json.dumps() — PythonのdictをJSON文字列にシリアライズする

json モジュールはすべてのPythonインストールに付属しています — pip install は不要です。 json.dumps(obj) はPythonオブジェクト(dict、list、文字列、数値、bool、またはNone)を受け取り、 有効なJSONを含む str を返します。Pythonのdictation はJSON objectに見た目が似ていますが、 本質的に異なります: dictはメモリ上のPythonデータ構造であり、 JSON文字列はシリアライズされたテキストです。 json.dumps() がその橋渡しをします。

最小限の例 — 1つのCSV行をJSONに変換

Python 3.10+
import json

# A single CSV row represented as a Python dict
server_entry = {
    "hostname": "web-prod-03",
    "ip_address": "10.0.12.47",
    "port": 8080,
    "region": "eu-west-1"
}

# Convert dict to JSON string
json_string = json.dumps(server_entry)
print(json_string)
# {"hostname": "web-prod-03", "ip_address": "10.0.12.47", "port": 8080, "region": "eu-west-1"}
print(type(json_string))
# <class 'str'>

これはコンパクトな1行JSONを生成します — ペイロードやストレージには適していますが、可読性は低いです。 indent=2 を追加すると人間が読みやすい出力になります:

Python 3.10+ — pretty-printed output
import json

server_entry = {
    "hostname": "web-prod-03",
    "ip_address": "10.0.12.47",
    "port": 8080,
    "region": "eu-west-1"
}

pretty_json = json.dumps(server_entry, indent=2)
print(pretty_json)
# {
#   "hostname": "web-prod-03",
#   "ip_address": "10.0.12.47",
#   "port": 8080,
#   "region": "eu-west-1"
# }

ほぼ毎回使用する2つのパラメータがあります: sort_keys=True は辞書のキーをアルファベット順に並べ替え(バージョン間でJSONファイルの差分を取るのに便利)、 ensure_ascii=False はASCII以外の文字を \uXXXX シーケンスにエスケープせずそのまま保持します。

Python 3.10+ — sort_keys and ensure_ascii
import json

warehouse_record = {
    "sku": "WH-9031",
    "location": "大阪倉庫3号",
    "quantity": 240,
    "last_audit": "2026-03-10"
}

output = json.dumps(warehouse_record, indent=2, sort_keys=True, ensure_ascii=False)
print(output)
# {
#   "last_audit": "2026-03-10",
#   "location": "大阪倉庫3号",
#   "quantity": 240,
#   "sku": "WH-9031"
# }

separators パラメータについて: デフォルトは (", ", ": ") でカンマとコロンの後にスペースが付きます。最もコンパクトな出力(JSONをURLパラメータに埋め込む場合やAPIレスポンスのバイト数を節約する場合に有用)を得るには、 separators=(",", ":") を渡します。

注意:Pythonのdictとjson objectは見た目がほぼ同じです。違いは: json.dumps() はPythonの True をJSONの trueに、 None nullに変換し、文字列をダブルクォートで囲みます (PythonはシングルクォートもJSONは許可していません)。有効なJSONを生成するには常に json.dumps() を使用してください — str()repr() に頼ってはいけません。

csv.DictReaderからJSONファイルへ — 完全なパイプライン

最も一般的な実務タスクは、CSVファイル全体を読み込んでJSONとして保存することです。 10行未満のエンドツーエンドスクリプトを紹介します。 csv.DictReader dict オブジェクトのイテレータを生成します — 1行につき1つ、最初の行をキーとして使用します。 list() で囲むことですべての行をPythonのリストに収集し、それがJSON配列にシリアライズされます。

Python 3.10+ — full CSV to JSON conversion
import csv
import json

# Step 1: Read CSV rows into a list of dicts
with open("inventory.csv", "r", encoding="utf-8") as csv_file:
    rows = list(csv.DictReader(csv_file))

# Step 2: Write the list as a JSON file
with open("inventory.json", "w", encoding="utf-8") as json_file:
    json.dump(rows, json_file, indent=2, ensure_ascii=False)

print(f"Converted {len(rows)} rows to inventory.json")

2つの open() 呼び出し: 1つはCSVの読み込み用、もう1つはJSONの書き込み用です。これがパターンの全体像です。 ここでは json.dump() sなし)を使用していることに注目してください — ファイルハンドルに直接書き込みます。 json.dumps() を使うと文字列が返され、それを別途 f.write() で書き込む必要があります。 json.dump() はメモリ上でJSON文字列全体を構築せずに出力をストリームするため、メモリ効率が高いです。

JSONをファイルではなく文字列として必要とする場合 — APIペイロードへの埋め込み、 標準出力への表示、データベースのカラムへの挿入など — json.dumps() に切り替えます:

Python 3.10+ — CSV rows as JSON string
import csv
import json

with open("sensors.csv", "r", encoding="utf-8") as f:
    rows = list(csv.DictReader(f))

# Get the JSON as a string instead of writing to a file
json_payload = json.dumps(rows, indent=2)
print(json_payload)
# [
#   {
#     "sensor_id": "TMP-4401",
#     "location": "7号館 2階",
#     "reading": "22.4",
#     "unit": "celsius"
#   },
#   ...
# ]

単一行 vs. 全データセット: json.dumps(single_dict) を呼び出すとJSON object({...})が得られます。 json.dumps(list_of_dicts) を呼び出すとJSON配列([{...}, {...}])が得られます。 外側のコンテナの形状は渡したものに依存します。多くのダウンストリームの受信者は表形式データに配列を期待します。

文字列以外の値の処理 — CSVからの型変換

初めて使う人が必ず引っかかるポイントがあります: csv.DictReader はすべての値を文字列として返します。CSVの数値 42 は辞書内で文字列 "42" になります。これを json.dumps() で直接シリアライズすると、JSONには "quantity": 42 ではなく "quantity": "42" が含まれます。型を検証するAPIはこれを拒否します。値を明示的に変換する必要があります。

Python 3.10+ — type coercion for CSV rows
import csv
import json

def coerce_types(row: dict) -> dict:
    """Convert string values to appropriate Python types."""
    return {
        "sensor_id": row["sensor_id"],
        "location": row["location"],
        "temperature": float(row["temperature"]),
        "humidity": float(row["humidity"]),
        "battery_pct": int(row["battery_pct"]),
        "active": row["active"].lower() == "true",
    }

with open("sensor_readings.csv", "r", encoding="utf-8") as f:
    rows = [coerce_types(row) for row in csv.DictReader(f)]

print(json.dumps(rows[0], indent=2))
# {
#   "sensor_id": "TMP-4401",
#   "location": "7号館 2階",
#   "temperature": 22.4,
#   "humidity": 58.3,
#   "battery_pct": 87,
#   "active": true
# }

これでJSON出力においてtemperatureはfloat、 battery_pctは整数、 activeはbooleanになります。 型変換関数はCSVのスキーマに固有のものです — CSVデータから型を推測する汎用的な方法はないため、CSVのフォーマットごとに1つの関数を書きます。

カスタムオブジェクトと非標準型のシリアライズ

Pythonの json モジュールは datetime UUID Decimal、 またはカスタムクラスをそのままシリアライズできません。これらに対して json.dumps() を呼び出すと TypeError が送出されます。これを処理する2つのアプローチがあります。

アプローチ1: default=パラメータ

未知の型をシリアライズ可能なものに変換する関数を default= に渡します。この関数はJSONエンコーダが処理方法を知らないオブジェクトに対してのみ呼び出されます。

Python 3.10+ — default= for datetime, UUID, Decimal
import json
from datetime import datetime
from decimal import Decimal
from uuid import UUID

def json_serial(obj):
    """Fallback serializer for non-standard types."""
    if isinstance(obj, datetime):
        return obj.isoformat()
    if isinstance(obj, UUID):
        return str(obj)
    if isinstance(obj, Decimal):
        return float(obj)
    raise TypeError(f"Type {type(obj).__name__} is not JSON serializable")

transaction = {
    "txn_id": UUID("a1b2c3d4-e5f6-7890-abcd-ef1234567890"),
    "amount": Decimal("149.99"),
    "currency": "EUR",
    "processed_at": datetime(2026, 3, 15, 14, 30, 0),
    "gateway": "stripe",
}

print(json.dumps(transaction, indent=2, default=json_serial))
# {
#   "txn_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
#   "amount": 149.99,
#   "currency": "EUR",
#   "processed_at": "2026-03-15T14:30:00",
#   "gateway": "stripe"
# }
警告:default= 関数の末尾では、認識できない型に対して必ず TypeError を送出してください。 None を返したり黙って無視したりすると、データが失われたことを示す兆候なしに出力に null が現れます。

アプローチ2: asdict()を使ったDataclasses

Pythonのdataclassesを使うと、CSVの各行に適切な型定義を持たせることができます。 dataclasses.asdict() でdataclassインスタンスをプレーンなdictに変換し、 json.dumps() に渡します。

Python 3.10+ — dataclass serialization
import json
from dataclasses import dataclass, asdict
from datetime import datetime

@dataclass
class ShipmentRecord:
    tracking_id: str
    origin: str
    destination: str
    weight_kg: float
    shipped_at: datetime

def json_serial(obj):
    if isinstance(obj, datetime):
        return obj.isoformat()
    raise TypeError(f"Not serializable: {type(obj).__name__}")

shipment = ShipmentRecord(
    tracking_id="SHP-9827",
    origin="大阪",
    destination="東京",
    weight_kg=1240.5,
    shipped_at=datetime(2026, 3, 12, 8, 0, 0),
)

print(json.dumps(asdict(shipment), indent=2, default=json_serial))
# {
#   "tracking_id": "SHP-9827",
#   "origin": "大阪",
#   "destination": "東京",
#   "weight_kg": 1240.5,
#   "shipped_at": "2026-03-12T08:00:00"
# }
注意:asdict() はネストされたdataclassを再帰的にdictに変換します。 dataclassが他のdataclassのリストを含む場合、ツリー全体が変換されます — 追加コードは不要です。

json.dumps() パラメータリファレンス

json.dumps() json.dump() が受け付けるキーワード引数の完全なリストです。 両方の関数は同一のパラメータを受け付けます — json.dump() はファイルオブジェクト用の追加の第1引数を取ります。

パラメータ
デフォルト
説明
obj
Any
(必須)
シリアライズ対象のPythonオブジェクト — dict、list、str、int、float、bool、None
indent
int | str | None
None
インデントレベルあたりのスペース数(または文字列)。None = コンパクトな1行出力
sort_keys
bool
False
辞書のキーをアルファベット順に並べ替えて出力する
ensure_ascii
bool
True
ASCII以外の文字を\\uXXXXとしてエスケープする。FalseにするとUTF-8を直接出力する
default
Callable | None
None
デフォルトでシリアライズできないオブジェクトに対して呼び出される関数 — シリアライズ可能な値を返すかTypeErrorを送出する
separators
tuple[str, str] | None
None
(item_separator, key_separator)を上書きする。スペースなしのコンパクト出力には(",", ":")を使用する
skipkeys
bool
False
str、int、float、bool、None以外の辞書キーをTypeErrorを送出せずにスキップする
allow_nan
bool
True
float("nan")、float("inf")、float("-inf")を許可する。Falseにするとこれらの値でValueErrorを送出する
cls
Type[JSONEncoder] | None
None
デフォルトの代わりに使用するカスタムJSONEncoderサブクラス

csv.DictReader — CSVをPythonのdictに読み込む

csv.DictReader はCSV-to-JSONパイプラインのもう一方の役割を担います。ファイルオブジェクトをラップし、 最初の行をフィールド名として使用して1行につき1つの dict を生成します。 csv.reader (プレーンなリストを生成)と比べると、DictReaderはカラムへの名前付きアクセスができます — row[3] のような魔法の索引は不要です。

Python 3.10+ — DictReader with custom delimiter
import csv
import json

# Tab-separated file from a database export
with open("user_sessions.tsv", "r", encoding="utf-8") as f:
    reader = csv.DictReader(f, delimiter="\t")
    sessions = list(reader)

print(json.dumps(sessions[:2], indent=2))
# [
#   {
#     "session_id": "sess_8f2a91bc",
#     "user_id": "usr_4421",
#     "started_at": "2026-03-15T09:12:00Z",
#     "duration_sec": "342",
#     "pages_viewed": "7"
#   },
#   {
#     "session_id": "sess_3c7d44ef",
#     "user_id": "usr_1187",
#     "started_at": "2026-03-15T09:14:22Z",
#     "duration_sec": "128",
#     "pages_viewed": "3"
#   }
# ]
警告:csv.DictReader はファイル全体を遅延読み込みします — 1行ずつ生成します。 list(reader) を呼び出すとすべての行がメモリに読み込まれます。数百万行のファイルの場合は、 すべてを収集するのではなく、ストリーミング方式で行を処理してください。

ファイルとAPIレスポンスからCSVを変換する

2つの本番シナリオ: ディスクからCSVファイルを読み込んで変換する場合と、 APIエンドポイントからCSVデータを取得する場合(多くのレポートサービスはCSVを返します)です。 どちらも適切なエラー処理が必要です。

CSVファイルを読み込む → 変換 → JSONを書き込む

Python 3.10+ — file conversion with error handling
import csv
import json
import sys

def csv_to_json_file(csv_path: str, json_path: str) -> int:
    """Convert a CSV file to JSON. Returns the number of rows written."""
    try:
        with open(csv_path, "r", encoding="utf-8") as f:
            rows = list(csv.DictReader(f))
    except FileNotFoundError:
        print(f"Error: {csv_path} not found", file=sys.stderr)
        sys.exit(1)
    except csv.Error as e:
        print(f"CSV parse error in {csv_path}: {e}", file=sys.stderr)
        sys.exit(1)

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

    return len(rows)

count = csv_to_json_file("fleet_vehicles.csv", "fleet_vehicles.json")
print(f"Wrote {count} records to fleet_vehicles.json")

APIからCSVを取得 → 解析 → JSON

Python 3.10+ — API CSV response to JSON
import csv
import io
import json
import urllib.request

def fetch_csv_as_json(url: str) -> str:
    """Fetch CSV from a URL and return it as a JSON string."""
    try:
        with urllib.request.urlopen(url, timeout=10) as resp:
            raw = resp.read().decode("utf-8")
    except urllib.error.URLError as e:
        raise RuntimeError(f"Failed to fetch {url}: {e}")

    reader = csv.DictReader(io.StringIO(raw))
    rows = list(reader)

    if not rows:
        raise ValueError("CSV response was empty or had no data rows")

    return json.dumps(rows, indent=2, ensure_ascii=False)

# Example: export endpoint that returns CSV
try:
    result = fetch_csv_as_json("https://reports.internal/api/v2/daily-metrics.csv")
    print(result)
except (RuntimeError, ValueError) as e:
    print(f"Error: {e}")

どちらの例でも、すべてのファイルオープン時に明示的な encoding="utf-8" を使用しています。これはASCII以外の文字を含むCSVファイル — アクセント付きの名前、特殊文字を含む住所、CJKテキスト — にとって重要です。明示的なエンコーディングなしでは、PythonはシステムのデフォルトにフォールバックしますがWindowsではしばしば cp1252 となり、マルチバイト文字が気づかないうちに化けます。

json.loads()によるJSON出力の検証

CSVをJSON文字列に変換した後、 json.loads() で再解析することで結果を検証できます。 このラウンドトリップにより、エンコーディングの問題、壊れたエスケープシーケンス、 または無効なJSONを生成する誤った文字列の結合を検出できます。 呼び出しをtry/exceptブロックで囲みます。

Python 3.10+ — round-trip validation
import json

json_string = json.dumps({"order_id": "ORD-7291", "total": 129.99})

# Verify it is valid JSON by parsing it back
try:
    parsed = json.loads(json_string)
    print(f"Valid JSON with {len(parsed)} keys")
except json.JSONDecodeError as e:
    print(f"Invalid JSON: {e}")
# Valid JSON with 2 keys

コマンドラインでのCSVからJSONへの変換

スクリプトファイルなしでターミナルから素早く変換します。Pythonの -c フラグはインラインコードを実行し、結果を python3 -m json.tool にパイプすることで整形表示できます。

bash — one-liner CSV to JSON
python3 -c "
import csv, json, sys
rows = list(csv.DictReader(sys.stdin))
json.dump(rows, sys.stdout, indent=2)
" < inventory.csv > inventory.json
bash — pipe CSV file and format with json.tool
python3 -c "import csv,json,sys; print(json.dumps(list(csv.DictReader(sys.stdin))))" < data.csv | python3 -m json.tool
bash — convert and validate with jq
python3 -c "import csv,json,sys; json.dump(list(csv.DictReader(sys.stdin)),sys.stdout)" < report.csv | jq .
注意:python3 -m json.tool は組み込みのJSONフォーマッターです。 標準入力からJSONを読み込み、検証し、4スペースのインデントで整形して出力します。 CSVからJSONへの変換が有効な出力を生成したかを確認するのに役立ちます。 2スペースのインデントが好みな場合やフィルタリングが必要な場合は、 jq を使用してください。

高性能な代替手段 — orjson

組み込みの json モジュールはほとんどのCSVファイルに対して問題なく機能します。しかし、ループ内で数万行のデータセットを処理する場合や、APIがリクエストごとにCSV由来のデータをシリアライズする必要がある場合、 orjson は5〜10倍高速です。Rustで書かれており、 str ではなく bytes を返し、カスタムの default= 関数なしで datetime UUID numpy 配列をネイティブにシリアライズします。

bash — install orjson
pip install orjson
Python 3.10+ — CSV to JSON with orjson
import csv
import orjson

with open("telemetry_events.csv", "r", encoding="utf-8") as f:
    rows = list(csv.DictReader(f))

# orjson.dumps() returns bytes, not str
json_bytes = orjson.dumps(rows, option=orjson.OPT_INDENT_2)

with open("telemetry_events.json", "wb") as f:  # note: "wb" for bytes
    f.write(json_bytes)

print(f"Wrote {len(rows)} events ({len(json_bytes)} bytes)")

APIは若干異なります: orjson.dumps() はbytesを返し、キーワード引数の代わりに option= フラグを使用します。orjsonの出力を書き込む際はバイナリ書き込みモード ("wb") でファイルを開きます。 文字列が必要な場合は、結果に対して .decode("utf-8") を呼び出します。

ターミナルのシンタックスハイライト — rich

ターミナルでCSVからJSONへの変換をデバッグする際、色付き出力があると便利です。 rich ライブラリはシンタックスハイライト付きでJSONを表示します — キー、文字列、数値、booleanがそれぞれ独自の色で表示されます。

bash — install rich
pip install rich
Python 3.10+ — rich JSON output
import csv
import json
from rich.console import Console
from rich.syntax import Syntax

console = Console()

with open("deployment_log.csv", "r", encoding="utf-8") as f:
    rows = list(csv.DictReader(f))

json_output = json.dumps(rows[:3], indent=2, ensure_ascii=False)
syntax = Syntax(json_output, "json", theme="monokai", line_numbers=True)
console.print(syntax)
警告:rich はANSIエスケープコードを出力に追加します。 richでフォーマットされた出力をファイルやAPIレスポンスに書き込まないでください — 目に見えない制御文字が含まれます。richはターミナル表示のみに使用してください。

大規模なCSVファイルの処理

500 MBのCSVファイルを list(csv.DictReader(f)) で読み込むとデータセット全体がメモリに確保され、その上に json.dump() がJSON文字列全体を構築します。50〜100 MBを超えるファイルには、 ストリーミング方式またはNDJSON(改行区切りJSON)— 1行につき1つのJSONオブジェクト — への書き込みに切り替えてください。

NDJSON — 1行に1つのJSONオブジェクト

Python 3.10+ — streaming CSV to NDJSON
import csv
import json

def csv_to_ndjson(csv_path: str, ndjson_path: str) -> int:
    """Convert CSV to NDJSON, processing one row at a time."""
    count = 0
    with open(csv_path, "r", encoding="utf-8") as infile, \
         open(ndjson_path, "w", encoding="utf-8") as outfile:
        for row in csv.DictReader(infile):
            outfile.write(json.dumps(row, ensure_ascii=False) + "\n")
            count += 1
    return count

rows_written = csv_to_ndjson("access_log.csv", "access_log.ndjson")
print(f"Wrote {rows_written} lines to access_log.ndjson")
# Each line is a standalone JSON object:
# {"timestamp":"2026-03-15T09:12:00Z","method":"GET","path":"/api/v2/orders","status":"200"}
# {"timestamp":"2026-03-15T09:12:01Z","method":"POST","path":"/api/v2/payments","status":"201"}

大規模なJSONの読み込みにijsonを使ったストリーミング

Python 3.10+ — ijson for reading large JSON
import ijson  # pip install ijson

def count_high_value_orders(json_path: str, threshold: float) -> int:
    """Count orders above a threshold without loading the full file."""
    count = 0
    with open(json_path, "rb") as f:
        for item in ijson.items(f, "item"):
            if float(item.get("total", 0)) > threshold:
                count += 1
    return count

# Process a 2 GB JSON file with constant memory usage
high_value = count_high_value_orders("all_orders.json", 500.0)
print(f"Found {high_value} orders above $500")
注意:CSVが50〜100 MBを超えたらNDJSONまたはストリーミングに切り替えてください。 ijson は大規模なJSONファイルを読み込むためのものです — 書き込み側では、上記のNDJSONパターンがファイルサイズに関わらずメモリ使用量を一定に保ちます。

よくある間違い

json.dumps()で文字列を取得してから別途ファイルに書き込む

問題: json.dumps()は文字列を返します。f.write()で書き込むことは機能しますが、メモリ内に不要な中間文字列を作成します — 大規模なデータセットでは無駄です。

修正: json.dump(data, f)を使ってファイルオブジェクトに直接書き込みます。完全な文字列を構築せずに出力をストリームします。

Before · Python
After · Python
json_string = json.dumps(rows, indent=2)
with open("output.json", "w") as f:
    f.write(json_string)  # unnecessary intermediate string
with open("output.json", "w", encoding="utf-8") as f:
    json.dump(rows, f, indent=2, ensure_ascii=False)  # direct write
CSVの文字列値を数値に変換し忘れる

問題: csv.DictReaderはすべての値を文字列として返します。JSON出力には"quantity": 5ではなく"quantity": "5"が含まれ、型を検証するAPIの受信者が拒否します。

修正: シリアライズ前にint()またはfloat()で数値カラムを明示的に変換します。

Before · Python
After · Python
rows = list(csv.DictReader(f))
json.dumps(rows)
# [{"port": "8080", "workers": "4"}]  ← strings, not numbers
rows = list(csv.DictReader(f))
for row in rows:
    row["port"] = int(row["port"])
    row["workers"] = int(row["workers"])
json.dumps(rows)
# [{"port": 8080, "workers": 4}]  ← proper integers
ファイルオープン時にencoding='utf-8'を省略する

問題: Windowsではデフォルトエンコーディングがcp1252です。ASCII以外の文字(アクセント付きの名前、CJKテキスト)が気づかないうちに文字化けするかUnicodeDecodeErrorが発生します。

修正: CSVの読み込みとJSONの書き込みの両方でopen()に常にencoding='utf-8'を渡します。

Before · Python
After · Python
with open("locations.csv", "r") as f:  # uses system default encoding
    rows = list(csv.DictReader(f))
with open("locations.csv", "r", encoding="utf-8") as f:
    rows = list(csv.DictReader(f))
json.dumps()の代わりにstr()またはrepr()を使う

問題: str(my_dict)はPython構文(シングルクォート、True、None)を生成し、これは有効なJSONではありません。APIとJSONパーサーはこれを拒否します。

修正: 有効なJSONを生成するには常にjson.dumps()を使用します。TrueをtrueにNoneをnullに変換し、ダブルクォートを使用します。

Before · Python
After · Python
output = str({"active": True, "note": None})
# "{'active': True, 'note': None}"  ← NOT valid JSON
output = json.dumps({"active": True, "note": None})
# '{"active": true, "note": null}'  ← valid JSON

json.dumps() vs 代替手段 — 比較一覧

メソッド
出力
有効なJSON
カスタム型
速度
インストール
json.dumps()
str
default=パラメータ経由
ベースライン
不要(標準ライブラリ)
json.dump()
ファイルに書き込み
default=パラメータ経由
ベースライン
不要(標準ライブラリ)
csv.DictReader + json
strまたはファイル
default=パラメータ経由
ベースライン
不要(標準ライブラリ)
pandas to_json()
strまたはファイル
datetimeをネイティブサポート
大規模データで約2倍高速
pip install pandas
orjson.dumps()
bytes
datetime/UUIDをネイティブサポート
5〜10倍高速
pip install orjson
dataclasses.asdict() + json
str
default=パラメータ経由
ベースライン
不要(標準ライブラリ)
polars write_json()
strまたはファイル
datetimeをネイティブサポート
大規模データで約3倍高速
pip install polars

ほとんどのCSVからJSONへの変換には、標準ライブラリの csv + json の組み合わせが適切な選択です: 依存関係なし、Pythonに付属、どこでも動作します。 プロファイリングでシリアライズがボトルネックであることが判明したときは orjson を使用してください — 大規模では速度の差は現実のものです。データのクリーニング、フィルタリング、またはJSONに変換する前の集計も必要な場合は pandas を使用します。 コードを書かずにすばやく変換したい場合は、オンラインCSV to JSONコンバーターが即座に処理します。

よくある質問

Pythonにおけるjson.dump()とjson.dumps()の違いは何ですか?

json.dump(obj, file)はJSONの出力をファイルライクオブジェクト(.write()メソッドを持つもの)に直接書き込みます。json.dumps(obj)はJSON形式の文字列を返します。ファイルへの書き込みにはjson.dump()を使用し、ログ出力・ペイロードへの埋め込み・ソケット送信などでPython文字列としてJSONが必要な場合はjson.dumps()を使用します。どちらも同じキーワード引数(indent、sort_keys、ensure_ascii、default)を受け付けます。

PythonでdictをJSON文字列に変換するにはどうすればよいですか?

json.dumps(your_dict)を呼び出します。戻り値は有効なJSONを含むstrです。読みやすい出力にはindent=2を追加します。dictにASCII以外の値が含まれる場合は、ensure_ascii=Falseを渡すとアクセント文字やCJK文字がそのまま保持されます。

Python 3.10+
import json

server_config = {"host": "api.internal", "port": 8443, "debug": False}
json_string = json.dumps(server_config, indent=2)
print(json_string)
# {
#   "host": "api.internal",
#   "port": 8443,
#   "debug": false
# }

PythonのdictのリストをJSONファイルとして保存するにはどうすればよいですか?

UTF-8エンコーディングで書き込みモードでファイルを開き、json.dump(your_list, f, indent=2, ensure_ascii=False)を呼び出します。ファイル出力には常にjson.dump()(json.dumps()ではなく)を使用してください — メモリに中間文字列を作成せずに、ファイルハンドルに直接書き込みます。

Python 3.10+
import json

records = [
    {"order_id": "ORD-4821", "total": 129.99, "currency": "USD"},
    {"order_id": "ORD-4822", "total": 89.50, "currency": "EUR"},
]

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

なぜjson.dumps()はTrueをtrueに、Noneをnullにするのですか?

PythonのbooleAN(True、False)とNoneは有効なJSONトークンではありません。JSON仕様では小文字のtrue、false、nullを使用します。json.dumps()はこの変換を自動的に処理します — TrueはtrueになりFalseはfalseになりNoneはnullになります。手動で変換する必要はありません。逆方向では、json.loads()がこれらをPythonの型に戻します。

CSVデータをJSONに変換する際にdatetimeオブジェクトを扱うにはどうすればよいですか?

datetimeオブジェクトをISO 8601文字列に変換するdefault=関数をjson.dumps()に渡します。default関数は、jsonがネイティブにシリアライズできないオブジェクトに対して呼び出されます。datetimeインスタンスにはobj.isoformat()を返し、それ以外の型にはTypeErrorを送出します。

Python 3.10+
import json
from datetime import datetime

def json_default(obj):
    if isinstance(obj, datetime):
        return obj.isoformat()
    raise TypeError(f"Not serializable: {type(obj)}")

event = {"action": "login", "timestamp": datetime(2026, 3, 15, 9, 30, 0)}
print(json.dumps(event, default=json_default))
# {"action": "login", "timestamp": "2026-03-15T09:30:00"}

pandasなしでCSVをJSONに変換できますか?

はい。Python標準ライブラリで必要なものはすべて揃っています。csv.DictReaderを使って各行をdictとして読み込み、行をリストに集め、json.dump()またはjson.dumps()でシリアライズします。サードパーティライブラリは不要です。pandasが必要になるのは、データのクリーニング・型推論が必要な場合や、プロジェクト内ですでに使用している場合だけです。

Python 3.10+
import csv
import json

with open("inventory.csv", "r", encoding="utf-8") as csv_file:
    rows = list(csv.DictReader(csv_file))

with open("inventory.json", "w", encoding="utf-8") as json_file:
    json.dump(rows, json_file, indent=2, ensure_ascii=False)

Pythonを書かない1クリックの代替手段としては、CSV to JSON コンバーターをお試しください — CSVデータを貼り付けるだけでフォーマット済みのJSONがすぐに出力されます。

関連ツール

MS
Maria SantosBackend Developer

Maria is a backend developer specialising in Python and API integration. She has broad experience with data pipelines, serialisation formats, and building reliable server-side services. She is an active member of the Python community and enjoys writing practical, example-driven guides that help developers solve real problems without unnecessary theory.

PS
Priya Sharma技術レビュアー

Priya is a data scientist and machine learning engineer who has worked across the full Python data stack — from raw data ingestion and cleaning to model deployment and monitoring. She is passionate about reproducible research, Jupyter-based workflows, and the practical engineering side of ML. She writes about NumPy, Pandas, data serialisation, and the Python patterns that make data pipelines reliable at scale.