閉じる

PythonでCSVを読み込む・書き出す(csvモジュールの使い方)

CSVは最も扱いやすいデータ交換形式の1つです。

Pythonでは標準ライブラリのcsvモジュールだけで、読み込みも書き出しも簡単に扱えます。

本記事では、初心者の方でも迷わないように、読み方の基本からヘッダーや区切り文字の扱い、文字化けや改行などのつまずきポイントの対処までを丁寧に解説します。

Pythonのcsvモジュールの基本

CSVとは

CSV(Comma-Separated Values)は、1行が1レコード、カンマで列を区切るプレーンテキスト形式です。

値の中にカンマや改行が含まれる場合は二重引用符で囲み、二重引用符そのものは""と二重化して表します。

ファイル拡張子は.csvが一般的で、Excelなど多くのソフトで開けます。

csvモジュールをインポートする

csvは標準ライブラリなので追加インストールは不要です。

使うときは通常どおりimportします。

Python
# csvモジュールのインポート
import csv

# よく使うクラスや定数を個別に参照することもできます
from csv import reader, writer, DictReader, DictWriter, QUOTE_ALL
ポイント

csvは読み込み用csv.reader、書き込み用csv.writer、列名ベースのcsv.DictReadercsv.DictWriterなどで構成されています。

サンプルCSVを用意する

学習用に小さなCSVを作成します。

Windowsでの改行増殖問題を避けるため、open(..., newline="")を必ず指定します。

文字化けを避けるためも含め、ここではencoding="utf-8"で保存します。

Python
# people.csv を作成するサンプル。初回だけ実行してください。
import csv

rows = [
    ["id", "name", "age"],  # ヘッダー
    [1, "Alice", 30],
    [2, "Bob", 25],
    [3, "Carol", 27],
]

# newline="" は必須。csvモジュールに改行制御を任せます
with open("people.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerows(rows)

print("people.csv を作成しました")
実行結果
people.csv を作成しました

作成されたファイルは次のような内容です。

CSV
id,name,age
1,Alice,30
2,Bob,25
3,Carol,27

PythonでCSVを読み込む

csv.readerの基本

最もシンプルな読み込みはcsv.readerで行います。

1行ずつリストとして取得でき、値はすべて文字列として読み込まれます。

Python
import csv

with open("people.csv", "r", newline="", encoding="utf-8") as f:
    reader = csv.reader(f)  # デフォルトはカンマ区切り
    for row in reader:
        # row は ['1', 'Alice', '30'] のようなリスト
        print(row)
実行結果
['id', 'name', 'age']
['1', 'Alice', '30']
['2', 'Bob', '25']
['3', 'Carol', '27']
補足

数値として使いたいときはint(row[2])のように自分で型変換します。

全行をリスト化する

小さなCSVであれば、一気にメモリに読み込んでリスト化しても構いません。

大きなファイルではメモリ使用量に注意してください。

Python
import csv

with open("people.csv", "r", newline="", encoding="utf-8") as f:
    rows = list(csv.reader(f))

print(rows)  # ネストしたリストの形
実行結果
[['id', 'name', 'age'], ['1', 'Alice', '30'], ['2', 'Bob', '25'], ['3', 'Carol', '27']]

ヘッダー行の扱い

ヘッダー(1行目)を読み飛ばしたい場合はnext(reader)を使います。

ヘッダーを別変数に取っておくと後続処理で便利です。

Python
import csv

with open("people.csv", "r", newline="", encoding="utf-8") as f:
    reader = csv.reader(f)
    header = next(reader)  # 1行目を取得してスキップ
    print("ヘッダー:", header)
    for row in reader:
        # ここでは id と age を整数に変換してみます
        person_id = int(row[0])
        age = int(row[2])
        print(f"id={person_id}, name={row[1]}, age={age}")
実行結果
ヘッダー: ['id', 'name', 'age']
id=1, name=Alice, age=30
id=2, name=Bob, age=25
id=3, name=Carol, age=27

列名で読む

列番号ではなく列名でアクセスしたい場合はcsv.DictReaderが便利です。

各行が辞書(dict)として得られます。

Python
import csv

with open("people.csv", "r", newline="", encoding="utf-8") as f:
    reader = csv.DictReader(f)  # 1行目がフィールド名とみなされる
    for row in reader:
        # row は {"id": "1", "name": "Alice", "age": "30"} のような辞書
        name = row["name"]
        age = int(row["age"])
        print(f"{name} さんは {age} 歳です")
実行結果
Alice さんは 30 歳です
Bob さんは 25 歳です
Carol さんは 27 歳です

区切り文字を変える

TSV(タブ区切り)やセミコロン区切りなど、区切り文字がカンマ以外のCSVもdelimiter引数で対応できます。

Python
import csv

# まずはタブ区切りのファイルを作って読み書きしてみます
rows = [
    ["id", "name", "score"],
    [1, "Alice", 88],
    [2, "Bob", 92],
]

# 書き出し(タブ区切り)
with open("people.tsv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f, delimiter="\t")
    writer.writerows(rows)

# 読み込み(タブ区切り)
with open("people.tsv", "r", newline="", encoding="utf-8") as f:
    reader = csv.reader(f, delimiter="\t")
    for row in reader:
        print(row)
実行結果
['id', 'name', 'score']
['1', 'Alice', '88']
['2', 'Bob', '92']
応用

セミコロン区切りの場合はdelimiter=";"を指定します。

PythonでCSVを書き出す

csv.writerの基本

最もシンプルな書き出しはcsv.writerを使います。

1行ずつwriterow、複数行を一括ならwriterowsです。

Python
import csv

data = [
    [1, "Orange", 120],
    [2, "Apple", 80],
]

with open("fruits.csv", "w", newline="", encoding="utf-8") as f:
    w = csv.writer(f)
    w.writerow(["id", "name", "price"])  # 1行だけ書く
    w.writerows(data)                     # 複数行をまとめて書く

print("fruits.csv を出力しました")
実行結果
fruits.csv を出力しました

出力されたファイルは次のようになります。

CSV
id,name,price
1,Orange,120
2,Apple,80

ヘッダー付きで書く

ヘッダーを自前で書く方法と、辞書ベースのDictWriterで列名と値を対応づけて書く方法があります。

値の並び順や欠損に強いのはDictWriterです。

Python
# 1) writerで手動ヘッダー + 行データ
import csv

headers = ["id", "fruit", "price"]
rows = [
    [1, "Orange", 120],
    [2, "Apple", 80],
]

with open("fruits_with_header.csv", "w", newline="", encoding="utf-8") as f:
    w = csv.writer(f)
    w.writerow(headers)   # ヘッダー
    w.writerows(rows)     # 本体

# 2) DictWriterで辞書から書く(列名の順序は fieldnames で明示)
from csv import DictWriter

items = [
    {"id": 1, "fruit": "Orange", "price": 120},
    {"id": 2, "fruit": "Apple", "price": 80},
]

with open("fruits_dict.csv", "w", newline="", encoding="utf-8") as f:
    w = DictWriter(f, fieldnames=["id", "fruit", "price"])
    w.writeheader()       # ヘッダーを自動生成して書く
    w.writerows(items)    # 辞書のリストをまとめて書く

既存CSVに追記する

既存ファイルの末尾に行を追記するにはmode="a"(append)で開きます。

重複ヘッダーに注意してください。

Python
import csv

# 既存の fruits_with_header.csv に1行だけ追加
with open("fruits_with_header.csv", "a", newline="", encoding="utf-8") as f:
    w = csv.writer(f)
    w.writerow([3, "Banana", 60])

# 追記されたか確認して末尾3行を表示
with open("fruits_with_header.csv", "r", newline="", encoding="utf-8") as f:
    tail = list(csv.reader(f))[-3:]
    for row in tail:
        print(row)
実行結果
['id', 'fruit', 'price']
['1', 'Orange', '120']
['2', 'Apple', '80']
備考

直前の出力例では追記1行の前後も表示しているため、ヘッダーや既存行が含まれています。

実際には最後に[csv writerow]で書いた1行が末尾に増えます。

初心者が知っておくと安心なポイント

改行が増える問題の対処

WindowsでCSVを書き出すと、行間に空行が入ってしまうことがあります。

原因はopen時の改行自動変換とcsv内部の改行処理が二重で働くためです。

対処はシンプルで、open(..., newline="")を常に指定します。

読み込み時もnewline=""を付けると安全です。

文字化けを避ける基本

まずはencoding="utf-8"で保存しておけばPythonや多くのツールで問題なく読めます。

ただし、Windows版Excelは既定でUTF-8のBOMなしを正しく認識しない場合があるため、Excelに渡す用途ではencoding="utf-8-sig"を選ぶと安心です。

日本語Windowsのレガシー互換が必要ならcp932(Shift_JIS互換)も選択肢です。

環境ごとのおすすめエンコーディングまとめ:

ツールや用途推奨エンコーディング補足
Python間のやり取り、Git管理utf-8標準的で相互運用性が高い
Windows版Excelで開くutf-8-sigBOMありUTF-8。Excelが文字化けしにくい
レガシーWindows互換が最優先cp932絵文字や一部文字で注意が必要

読み込み時のBOM対策: BOM付きファイルはencoding="utf-8-sig"で読み込むと先頭の不可視文字を自動除去できます。

カンマや改行を含む値の扱い

CSVのセル値にカンマや改行、ダブルクォートが含まれても、csvモジュールは自動的に適切なクォートやエスケープを行います。

必要に応じてquotingquotecharなどを調整できます。

Python
import csv

rows = [
    ["id", "text"],
    [1, "カンマ,入りのテキスト"],         # カンマを含む
    [2, "複数行\nのメモです"],             # 改行を含む
    [3, 'ダブルクォート " を含む'],        # 二重引用符を含む
]

# デフォルト設定で書き出す(必要なときだけ引用符を付ける QUOTE_MINIMAL)
with open("special.csv", "w", newline="", encoding="utf-8") as f:
    w = csv.writer(f)  # quotingの既定値は csv.QUOTE_MINIMAL
    w.writerows(rows)

# 書かれた内容を確認(人間が見るためにファイル内容をそのまま表示)
with open("special.csv", "r", encoding="utf-8") as f:
    print(f.read())

# 読み戻しも正しく復元されることを確認
with open("special.csv", "r", newline="", encoding="utf-8") as f:
    r = csv.reader(f)
    for row in r:
        print(row)
実行結果
id,text
1,"カンマ,入りのテキスト"
2,"複数行
のメモです"
3,"ダブルクォート "" を含む"
['id', 'text']
['1', 'カンマ,入りのテキスト']
['2', '複数行\nのメモです']
['3', 'ダブルクォート " を含む']

必要に応じてクォート方針を変更できます。

quoting値意味注意点
csv.QUOTE_MINIMAL(既定)必要なときだけ引用手軽で多くのツールと互換
csv.QUOTE_ALLすべてのフィールドを引用ファイルがやや大きくなる
csv.QUOTE_NONNUMERIC非数値のみ引用、読み込み時は数値をfloatに変換厳密な型管理に不向きな場合あり
csv.QUOTE_NONEまったく引用しないカンマや改行を含む値が壊れるため非推奨。使うならescapechar必須

その他パラメータ:

  • quotechar='"': 引用符の文字
  • escapechar='\': クォートしない場合などのエスケープ文字
  • lineterminator="\n": 改行コード。通常は既定のままでOK
  • dialect="excel": 代表的な設定のプリセット。独自定義も可能

迷ったら既定値のままで始め、必要になったらquotingなどを調整すると安全です。

まとめ

本記事では、Python標準のcsvモジュールでCSVを読み書きする実践的な方法を解説しました。

基本のcsv.readercsv.writer、ヘッダー処理やDictReader、区切り文字の変更方法、さらに初心者がつまずきやすいnewline=""encodingの選び方、クォート設定までをひと通り押さえました。

最初はopen(..., newline="", encoding="utf-8")を合言葉にし、DictReaderDictWriterで列名ベースの操作に慣れると、現場のCSV処理が格段に楽になります。

必要になったときだけdelimiterquotingを調整し、確実な入出力を心がけてください。

この記事を書いた人
エーテリア編集部
エーテリア編集部

人気のPythonを初めて学ぶ方向けに、文法の基本から小さな自動化まで、実際に手を動かして理解できる記事を書いています。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!