CSVは最も扱いやすいデータ交換形式の1つです。
Pythonでは標準ライブラリのcsv
モジュールだけで、読み込みも書き出しも簡単に扱えます。
本記事では、初心者の方でも迷わないように、読み方の基本からヘッダーや区切り文字の扱い、文字化けや改行などのつまずきポイントの対処までを丁寧に解説します。
Pythonのcsvモジュールの基本
CSVとは
CSV(Comma-Separated Values)は、1行が1レコード、カンマで列を区切るプレーンテキスト形式です。
値の中にカンマや改行が含まれる場合は二重引用符で囲み、二重引用符そのものは""
と二重化して表します。
ファイル拡張子は.csv
が一般的で、Excelなど多くのソフトで開けます。
csvモジュールをインポートする
csv
は標準ライブラリなので追加インストールは不要です。
使うときは通常どおりimport
します。
# csvモジュールのインポート
import csv
# よく使うクラスや定数を個別に参照することもできます
from csv import reader, writer, DictReader, DictWriter, QUOTE_ALL
csv
は読み込み用csv.reader
、書き込み用csv.writer
、列名ベースのcsv.DictReader
やcsv.DictWriter
などで構成されています。
サンプルCSVを用意する
学習用に小さなCSVを作成します。
Windowsでの改行増殖問題を避けるため、open(..., newline="")
を必ず指定します。
文字化けを避けるためも含め、ここではencoding="utf-8"
で保存します。
# 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 を作成しました
作成されたファイルは次のような内容です。
id,name,age
1,Alice,30
2,Bob,25
3,Carol,27
PythonでCSVを読み込む
csv.readerの基本
最もシンプルな読み込みはcsv.reader
で行います。
1行ずつリストとして取得でき、値はすべて文字列として読み込まれます。
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であれば、一気にメモリに読み込んでリスト化しても構いません。
大きなファイルではメモリ使用量に注意してください。
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)
を使います。
ヘッダーを別変数に取っておくと後続処理で便利です。
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)として得られます。
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
引数で対応できます。
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
です。
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 を出力しました
出力されたファイルは次のようになります。
id,name,price
1,Orange,120
2,Apple,80
ヘッダー付きで書く
ヘッダーを自前で書く方法と、辞書ベースのDictWriter
で列名と値を対応づけて書く方法があります。
値の並び順や欠損に強いのはDictWriter
です。
# 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)で開きます。
重複ヘッダーに注意してください。
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-sig | BOMありUTF-8。Excelが文字化けしにくい |
レガシーWindows互換が最優先 | cp932 | 絵文字や一部文字で注意が必要 |
読み込み時のBOM対策: BOM付きファイルはencoding="utf-8-sig"
で読み込むと先頭の不可視文字を自動除去できます。
カンマや改行を含む値の扱い
CSVのセル値にカンマや改行、ダブルクォートが含まれても、csvモジュールは自動的に適切なクォートやエスケープを行います。
必要に応じてquoting
やquotechar
などを調整できます。
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"
: 改行コード。通常は既定のままでOKdialect="excel"
: 代表的な設定のプリセット。独自定義も可能
迷ったら既定値のままで始め、必要になったらquoting
などを調整すると安全です。
まとめ
本記事では、Python標準のcsv
モジュールでCSVを読み書きする実践的な方法を解説しました。
基本のcsv.reader
とcsv.writer
、ヘッダー処理やDictReader
、区切り文字の変更方法、さらに初心者がつまずきやすいnewline=""
やencoding
の選び方、クォート設定までをひと通り押さえました。
最初はopen(..., newline="", encoding="utf-8")
を合言葉にし、DictReader
やDictWriter
で列名ベースの操作に慣れると、現場のCSV処理が格段に楽になります。
必要になったときだけdelimiter
やquoting
を調整し、確実な入出力を心がけてください。