概要(DictReaderは「列名でアクセスできる」CSV読み込みの定番)
csv.DictReaderは、CSVの各行を「ヘッダーをキーにした辞書」として読み込める標準機能です。列名で参照できるので、インデックス番号を覚える必要がなく、可読性が抜群になります。重要なのは「エンコーディングと改行の扱い」「型変換・欠損値の安全処理」「ヘッダーがないCSVへの対応」です。with文でファイルを開き、必要に応じてfieldnamesやdialect(delimiterなど)を指定すれば、多くの現場のCSVを安全に扱えます。
基本の使い方(ここが重要)
ヘッダー行ありのCSVを辞書で読む
import csv
# 例: sample.csv の内容
# name,age,city
# Alice,30,New York
# Bob,25,Los Angeles
with open("sample.csv", newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
print(row) # {'name': 'Alice', 'age': '30', 'city': 'New York'} など
print(row["name"], int(row["age"]))
Python「newline=”」は改行の二重解釈を避けるための推奨設定です。値は文字列として読み込まれるため、数値が必要なら明示的に型変換します。
Pathlibと組み合わせて安全に扱う
from pathlib import Path
import csv
csv_path = Path("data/users.csv")
with csv_path.open(newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
...
PythonPath.openを使うと結合や存在確認と一体で扱えます。
重要ポイントの深掘り(ヘッダー・型変換・欠損・方言)
ヘッダーがないCSVはfieldnamesを手動指定
import csv
# 例: ヘッダーなし
# Alice,30,New York
# Bob,25,Los Angeles
with open("noheader.csv", newline="", encoding="utf-8") as f:
reader = csv.DictReader(f, fieldnames=["name", "age", "city"])
for row in reader:
print(row)
Python先頭行がデータの場合は、意図した列名を与えて辞書化します。先頭行をスキップしたいなら、事前に次(f)で1行読み捨てする方法もあります。
型変換とバリデーション(安全な変換関数の導入)
def to_int(s, default=None):
try:
return int(s)
except (TypeError, ValueError):
return default
with open("sample.csv", newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
age = to_int(row.get("age"))
if age is None:
# 欠損や不正値の扱いを統一(スキップ・ログ出力など)
continue
...
PythonDictReaderは値を文字列で渡すので、変換と検証は必須です。小さなユーティリティ関数に切り出すと、コード全体が安定します。
欠損列・余分列の扱い(restval・restkey・extrasaction)
import csv
with open("messy.csv", newline="", encoding="utf-8") as f:
reader = csv.DictReader(
f,
fieldnames=["name", "age", "city"],
restval="", # 足りない列のデフォルト値
restkey="__extra__", # 余分列のキー名(可変長行の吸収先)
)
for row in reader:
print(row.get("__extra__")) # 余分列があればここに入る
Python列不足をrestvalで埋め、列過多はrestkeyで受け止めると、崩れたCSVでも耐性が上がります。余分列を拒否したい場合は、読み取り後にチェックして例外を出す設計にします。
区切り文字や引用符など「方言」の指定
import csv
with open("data_semicolon.csv", newline="", encoding="utf-8") as f:
reader = csv.DictReader(f, delimiter=";", quotechar='"')
for row in reader:
...
PythonExcel由来などで「;」区切りになることがあります。delimiter・quotechar・escapecharを正しく指定すると、取りこぼしを防げます。
実務での使いどころ(クリーニング・集計・BOM・大規模)
クリーニングとフィルタ・集計の定番パターン
import csv
total = 0
count = 0
with open("sales.csv", newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
price = row.get("price", "").strip()
if not price:
continue
total += float(price)
count += 1
print("avg:", total / count if count else 0)
Pythonstripで空白を落とし、欠損をスキップしてから集計。最初に「必須列があるか」を検証するのも有効です。
UTF-8 BOM対策と改行の取り扱い
import csv
# BOM付きの可能性がある場合は utf-8-sig にすると先頭の不可視文字を除去
with open("maybe_bom.csv", newline="", encoding="utf-8-sig") as f:
reader = csv.DictReader(f)
...
PythonBOMがあるとヘッダーの先頭に不可視文字が付く事故が起きます。utf-8-sigで回避できます。
大規模CSVは「イテレートして処理、作らず流す」
import csv
with open("huge.csv", newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
for i, row in enumerate(reader, start=1):
# その場で処理(DB投入・書き出しなど)
...
if i % 100000 == 0:
print("processed:", i)
Python一度にメモリへ読み込まず、行ごとに処理します。ログを入れると進捗が見えて安心です。
例題で身につける(定番から一歩先まで)
例題1:基本読み込みと型変換
import csv
with open("users.csv", newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
uid = row["id"]
age = int(row["age"]) # 失敗可能なら try/except へ
print(uid, age)
Python例題2:ヘッダーなしCSVへの列名付与
import csv
with open("noheader.csv", newline="", encoding="utf-8") as f:
reader = csv.DictReader(f, fieldnames=["name", "age", "city"])
for row in reader:
print(row["name"], row["city"])
Python例題3:セミコロン区切り+引用符ありの読取り
import csv
with open("data_semicolon.csv", newline="", encoding="utf-8") as f:
reader = csv.DictReader(f, delimiter=";", quotechar='"')
for row in reader:
print(row)
Python例題4:欠損をrestvalで埋め、余分列をrestkeyへ逃がす
import csv
with open("ragged.csv", newline="", encoding="utf-8") as f:
reader = csv.DictReader(
f,
fieldnames=["id", "name", "score"],
restval=None,
restkey="__extra__",
)
for row in reader:
print(row["id"], row["name"], row["score"], row.get("__extra__"))
Python例題5:DictWriterと組み合わせて「読み→加工→書き」
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へ渡せば、列操作が明快になります。
まとめ
csv.DictReaderは「列名でアクセスできる」ことが最大の強みで、初心者でも安全に実務のCSVを扱えます。改行はnewline=”、エンコーディングはutf-8(BOMの可能性があればutf-8-sig)を基本に、値は文字列で来る前提で型変換・バリデーションを入れる。ヘッダーがない場合はfieldnamesを自前で定義し、崩れたCSVにはrestval・restkeyで耐性を持たせる。区切りや引用符はdialect指定で吸収し、巨大ファイルは行ごとに“作らず流す”。Pathlibとの併用で結合・存在確認・読み書きまで一貫させれば、短くて読みやすく、壊れないCSV処理が書けます。
