Python | ファイル操作など:CSV 読み書き

Python
スポンサーリンク

概要(CSV は「表データをテキストでやり取りする」最小で強力な形式)

CSV はカンマ区切りのテキストで表データを保存する形式です。Python では標準ライブラリの csv モジュールで、追加インストールなしに安全・正確に読み書きできます。重要なのは with 文で開く、encoding を明示(原則 UTF-8)、newline=”” を指定して余計な空行を防ぐこと、そして手書きの split より csv.reader/csv.writer を使うことです。

import csv

# 基本の読み込み
with open("data.csv", "r", encoding="utf-8", newline="") as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)  # 各行はリスト

# 基本の書き込み
rows = [["name", "qty"], ["coffee", 2], ["tea", 1]]
with open("out.csv", "w", encoding="utf-8", newline="") as f:
    writer = csv.writer(f)
    writer.writerows(rows)
Python

読み込みの基本(ここが重要)

行をリストとして受け取る

csv.reader は各行を「セルのリスト」として返します。前処理(strip や型変換)は読みながら行うのが安全です。

import csv

def load_items(path: str) -> list[tuple[str, int]]:
    items: list[tuple[str, int]] = []
    with open(path, "r", encoding="utf-8", newline="") as f:
        reader = csv.reader(f)
        header = next(reader, None)  # ヘッダがあれば一行読み捨て
        for row in reader:
            name, qty = row[0].strip(), int(row[1])
            items.append((name, qty))
    return items
Python

辞書形式で読みたいなら DictReader

ヘッダ行をキーにして、各行を辞書で受け取れます。列名でアクセスできるため可読性が高く、列の並び変更にも強いです。

import csv

with open("data.csv", "r", encoding="utf-8", newline="") as f:
    reader = csv.DictReader(f)  # 最初の行をキーにする
    for row in reader:
        print(row["name"], int(row["qty"]))
Python

区切り文字や引用符の調整(セミコロン区切りなど)

カンマ以外の区切り(; やタブ)や、引用符(”)の扱いは引数で制御できます。人手で split せず、方言(dialect)に合わせて reader を設定しましょう。

import csv

with open("semi.csv", "r", encoding="utf-8", newline="") as f:
    reader = csv.reader(f, delimiter=";", quotechar='"', escapechar="\\")
    for row in reader:
        print(row)
Python

書き込みの基本(ここが重要)

writer で行単位に正確に出力する

改行やエスケープ、セル中のカンマを自動処理してくれるため、文字列連結より確実です。newline=”” を忘れると余計な空行が入ることがあります。

import csv

rows = [
    ["name", "comment"],
    ["coffee", "rich, smooth"],  # カンマ入りでも安全
]
with open("out.csv", "w", encoding="utf-8", newline="") as f:
    writer = csv.writer(f)
    writer.writerows(rows)
Python

辞書形式で書くなら DictWriter

列名を定義し、辞書のキーに応じて整列・不足埋めも行えます。データ構造が辞書中心ならこちらが自然です。

import csv

fields = ["name", "qty", "note"]
rows = [
    {"name": "coffee", "qty": 2, "note": "ok"},
    {"name": "tea", "qty": 1, "note": ""},
]
with open("out.csv", "w", encoding="utf-8", newline="") as f:
    w = csv.DictWriter(f, fieldnames=fields)
    w.writeheader()
    w.writerows(rows)
Python

追記と上書きの使い分け

新規ファイル作成・上書きは “w”、既存末尾に追加は “a”。誤上書きを避けたい成果物は “x”(新規のみ)で安全に生成します。

import csv

new_row = ["sugar", 3]
with open("out.csv", "a", encoding="utf-8", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(new_row)
Python

実務での勘所(エンコーディング・改行・精度)

encoding は原則 UTF-8、Excel 互換が必要なら BOM 付き(UTF-8-SIG)

Excel で日本語が文字化けする場合、UTF-8 の BOM を付けると開きやすくなります。必要な場面のみ使い分けましょう。

# Excel互換優先(BOM付き)
with open("out_excel.csv", "w", encoding="utf-8-sig", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["名前", "数量"])
    writer.writerow(["コーヒー", 2])
Python

改行は newline=”” をセット(二重改行の防止)

csv モジュールは改行処理を内部で行います。open に newline=”” を渡すのが公式推奨で、Windows での空行混入を防ぎます。

「手書きの split/join」は罠が多い(引用・エスケープに弱い)

セル中のカンマ、改行、引用符、エスケープは手書きだと壊れがち。必ず csv.reader/csv.writer(または DictReader/DictWriter)を使い、仕様に任せるのが安全です。


応用テクニック(品質と柔軟性を高める)

Sniffer で形式を自動推定

区切り文字が不明な CSV を自動判別できます。混在データの一次解析に便利です。

import csv

with open("unknown.csv", "r", encoding="utf-8", newline="") as f:
    sample = f.read(2048)
    dialect = csv.Sniffer().sniff(sample)
    f.seek(0)
    reader = csv.reader(f, dialect)
    for row in reader:
        print(row)
Python

数値・日時の型変換を「読みながら」行う

まとめて読むのではなく、行ごとに型変換して即処理するとメモリ効率も良く、データ品質のチェックもしやすいです。

import csv
from datetime import datetime

def load_sales(path: str) -> list[tuple[datetime, str, int]]:
    out = []
    with open(path, "r", encoding="utf-8", newline="") as f:
        r = csv.DictReader(f)
        for row in r:
            ts = datetime.fromisoformat(row["timestamp"])
            item = row["item"]
            qty = int(row["qty"])
            out.append((ts, item, qty))
    return out
Python

大規模データは「ストリーミング処理」

全行をメモリに載せず、読みながら集計・フィルタ・書き出しへ流します。これが実務の安定運用の基本線です。

import csv

def filter_to_new(src: str, dst: str) -> None:
    with open(src, "r", encoding="utf-8", newline="") as fin, \
         open(dst, "w", encoding="utf-8", newline="") as fout:
        r = csv.DictReader(fin)
        w = csv.DictWriter(fout, fieldnames=r.fieldnames)
        w.writeheader()
        for row in r:
            if int(row["qty"]) >= 2:
                w.writerow(row)
Python

例題で身につける(定番から一歩先まで)

例題1:CSV を読み、合計を計算

import csv

def total_qty(path: str) -> int:
    total = 0
    with open(path, "r", encoding="utf-8", newline="") as f:
        for name, qty in csv.reader(f):
            total += int(qty)
    return total
Python

例題2:ヘッダつき CSV を辞書で読み、整形して保存

import csv

def normalize(src: str, dst: str) -> None:
    with open(src, "r", encoding="utf-8", newline="") as fin, \
         open(dst, "w", encoding="utf-8", newline="") as fout:
        r = csv.DictReader(fin)
        w = csv.DictWriter(fout, fieldnames=["name", "qty"])
        w.writeheader()
        for row in r:
            w.writerow({"name": row["name"].strip().casefold(),
                        "qty": int(row["qty"])})
Python

例題3:方言対応(セミコロン区切り)

import csv

def read_sc(path: str) -> list[list[str]]:
    with open(path, "r", encoding="utf-8", newline="") as f:
        reader = csv.reader(f, delimiter=";", quotechar="'")
        return [row for row in reader]
Python

例題4:Excel で開きやすい出力(BOM 付き)

import csv

def export_excel_friendly(path: str, rows: list[list[str]]) -> None:
    with open(path, "w", encoding="utf-8-sig", newline="") as f:
        csv.writer(f).writerows(rows)
Python

まとめ

CSV は「表データを最小コストで交換する」ための実用フォーマット。Python では csv モジュールで、読みは reader/DictReader、書きは writer/DictWriter を使うのが安全です。with 文、encoding(UTF-8/必要に応じて UTF-8-SIG)、newline=”” が三大必須。区切り・引用・エスケープは手書きせずモジュールに任せ、型変換は読みながら行う。大きなファイルはストリーミングで処理する。この基本線を守れば、初心者でも正確で拡張に強い CSV 処理を書けます。

タイトルとURLをコピーしました