概要(DictWriterは「列名で書ける」CSV出力の定番)
csv.DictWriterは、辞書(dict)をそのままCSVの行として書き込める標準機能です。列順やヘッダーを明示できるため、インデックスを意識せず「列名=キー」で安全・読みやすく出力できます。重要なのは「fieldnames(列名)の設計」「ヘッダーの書き出し」「欠損キー・余分キーの扱い」「改行とエンコーディング」です。with文で開いてnewline=”にするのが基本で、DictReaderと組み合わせると“読み→加工→書き”が自然につながります。
基本の使い方(ここが重要)
ヘッダー付きで辞書を行として書き込む
import csv
data = [
{"name": "Alice", "age": 30, "city": "New York"},
{"name": "Bob", "age": 25, "city": "Los Angeles"},
]
with open("output.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["name", "age", "city"])
writer.writeheader() # 最初にヘッダー行を書く
for row in data:
writer.writerow(row) # 辞書のキーを列名に対応させて1行書く
Pythonnewline=”は改行の二重発生(空行が入る問題)を防ぐための推奨設定です。fieldnamesは「列の順序と必須キー」を決めます。
Pathlibと組み合わせて安全に出力先を用意
from pathlib import Path
import csv
out = Path("reports/users.csv")
out.parent.mkdir(parents=True, exist_ok=True)
with out.open("w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["id", "name", "age"])
writer.writeheader()
writer.writerow({"id": 101, "name": "alice", "age": 30})
Python重要ポイントの深掘り(fieldnames・ヘッダー・欠損と余分・改行と文字コード)
fieldnames(列名)の決め方と整合性
- 列順の固定: fieldnamesの順がそのままCSVの列順になるので、読み手や後工程が想定する順番で定義します。
- 必須列の宣言: “必ず存在するキー”をfieldnamesに含め、欠損時の扱い(後述)をポリシー化します。
- 追加列の管理: 加工で列が増える場合は、事前にfieldnamesへ追加してからwriteheaderを呼びます。
writeheader(ヘッダー出力)は“最初に一度だけ”
- 明示的に出す: ファイル先頭に必ずヘッダーが必要なら、writeheaderを最初に実行。
- 追記モードでは重複回避: 追記(”a”)では既存ヘッダー有無を確認し、二重に書かない工夫が必要です。
欠損キー・余分キーの扱い(extrasaction / restval)
import csv
rows = [
{"id": 1, "name": "a"}, # age 欠損
{"id": 2, "name": "b", "age": 20, "city": "X"} # city は余分
]
with open("out.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(
f,
fieldnames=["id", "name", "age"],
extrasaction="ignore" # 余分キーは無視(例:cityを捨てる)
)
writer.writeheader()
for row in rows:
writer.writerow(row) # age 欠損は空セルになる
Python- 欠損キー: 指定列に対して辞書にキーが無い場合、そのセルは空文字で書かれます。必要なら前処理でデフォルト値をセット。
- 余分キー: extrasaction=”ignore”なら無視、未指定のまま余分キーがあるとValueErrorになるため、ポリシーを統一します。
- restval(DictReader側の概念)との違い: 書き込みにはrestvalは無く、欠損は空になります。書く前に欠損補完するのが安全です。
改行と文字コード(Excelなどの互換を意識)
- newline=” を徹底: csvモジュールは改行を自身で制御するため、openでnewline=”が必須。
- encoding: 迷ったらutf-8。WindowsでExcel互換を強めたい場合はutf-8-sig(BOM付き)で先頭の文字化け回避を考慮。
実務の使いどころ(加工出力・追記・列の追加・方言)
読み→加工→書き(DictReaderと直結)
import csv
with open("input.csv", newline="", encoding="utf-8") as fin, \
open("output.csv", "w", newline="", encoding="utf-8") as fout:
reader = csv.DictReader(fin)
fieldnames = reader.fieldnames + ["score2"] # 新列を増やす
writer = csv.DictWriter(fout, fieldnames=fieldnames)
writer.writeheader()
for row in reader:
row["score2"] = float(row["score"]) * 2 if row.get("score") else ""
writer.writerow(row)
PythonDictReaderで辞書を受け、そのままDictWriterへ。列追加・欠損補完が分かりやすく書けます。
既存ファイルへの追記(ヘッダー重複の防止)
import csv
from pathlib import Path
path = Path("log.csv")
exists = path.exists()
with path.open("a", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["time", "event"])
if not exists:
writer.writeheader()
writer.writerow({"time": "2025-12-15 17:06", "event": "start"})
Python新規作成時だけヘッダーを書き、既存にはデータだけ追記します。
区切り文字・引用符の指定(dialectの調整)
import csv
rows = [{"a": 1, "b": 'hello, "world"'}]
with open("semi.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(
f,
fieldnames=["a", "b"],
delimiter=";", # セミコロン区切り
quotechar='"',
quoting=csv.QUOTE_MINIMAL
)
writer.writeheader()
for r in rows:
writer.writerow(r)
PythonExcelや他システム由来の仕様に合わせ、delimiter・quotechar・quoting・escapecharを調整します。
例題で身につける(定番から一歩先まで)
例題1:欠損値をデフォルト補完して書く
import csv
rows = [{"id": 1, "name": "A"}, {"id": 2, "name": "B", "age": 20}]
def fill_defaults(row):
return {"id": row.get("id", ""), "name": row.get("name", ""), "age": row.get("age", 0)}
with open("filled.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["id", "name", "age"])
writer.writeheader()
for r in rows:
writer.writerow(fill_defaults(r))
Python例題2:余分キーを拒否(厳格モード)
import csv
rows = [{"id": 1, "name": "A", "age": 20}, {"id": 2, "name": "B", "age": 30, "city": "X"}]
with open("strict.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["id", "name", "age"]) # extrasactionを指定しない
writer.writeheader()
for r in rows:
writer.writerow(r) # 2行目で ValueError(余分キー)→ 例外で気付ける
Python例題3:BOM付きでExcel互換を上げる
import csv
with open("excel.csv", "w", newline="", encoding="utf-8-sig") as f:
writer = csv.DictWriter(f, fieldnames=["Name", "Age"])
writer.writeheader()
writer.writerow({"Name": "Taro", "Age": 25})
Python例題4:加工で列順を制御(表示・下流連携のため)
import csv
rows = [{"name": "Alice", "city": "NY", "age": 30},
{"name": "Bob", "city": "LA", "age": 25}]
order = ["name", "age", "city"] # 列順ポリシー
with open("ordered.csv", "w", newline="", encoding="utf-8") as f:
w = csv.DictWriter(f, fieldnames=order)
w.writeheader()
for r in rows:
w.writerow({k: r.get(k, "") for k in order})
Pythonまとめ
DictWriterは「列名でデータを書く」ための最短手段で、列順とヘッダーを明示できるのが最大の強みです。fieldnamesで順序と必須列を決め、writeheaderを冒頭で一度だけ。欠損キーは空になるため前処理で補完し、余分キーはextrasaction=”ignore”か厳格に例外で気付く設計にする。newline=”と適切なencodingを守り、必要ならdelimiterやquotingを調整。DictReaderと組み合わせて“読み→加工→書き”を一貫させれば、初心者でも短くて安全なCSV出力が書けます。
