【Python】csvモジュール完全ガイド!初心者がCSVの読み込み・書き込みでハマる点を徹底解説
PythonをコマンドプロンプトやPowerShellでPC上で動かすには、Pythonをダウンロードしてインストールする必要があります。
まだの方はPythonのインストールと開発環境の構築の記事を参考にして、Pythonをインストールしてください。
「プログラミングでCSVファイルを扱いたいけど、何から手をつければいいか分からない…」
こんにちは!ほんの数ヶ月前まで皆さんと同じ"元"初心者だった、このサイトの管理人です。AIの力を借りながら、1ヶ月半で2つのWebサイトを立ち上げた経験から言わせてください。CSVファイルの操作は、Web開発で避けては通れない、でもめちゃくちゃ便利なスキルです!
実際、私もお問い合わせフォームのデータを管理したり、商品リストを一括でアップロードしたりする機能を作るとき、このCSVの知識にめちゃくちゃ助けられました。
この記事では、そんな私の実体験(と、たくさんの失敗談…)を元に、Pythonの`csv`モジュールを使ってCSVファイルを自由自在に読み書きする方法を、世界一分かりやすく解説します。専門用語は極力使いません。この記事を読み終える頃には、あなたはCSVマスターになっているはずです!
準備運動:操作するサンプルCSVファイルを用意しよう
まずは、練習台となるCSVファイルを用意しましょう。以下の内容をコピーして、あなたのPCに`members.csv`という名前で保存してください。文字コードはUTF-8で保存するのがポイントです。(メモ帳で保存する際は、文字コードの選択肢があるはずです)
このファイルは、架空のWebサイトの会員リストを想定しています。
id,name,email
1,山田太郎,taro.yamada@example.com
2,鈴木花子,hanako.suzuki@example.com
3,佐藤次郎,jiro.sato@example.com
基本の「き」:CSVファイルを読み込んでみよう (`csv.reader`)
最初にやるのは、CSVファイルの中身をPythonで読み込むことです。先ほど作成した`members.csv`を読み込んで、その内容をコンソールに表示させてみましょう。
はい、結論のコードから!これをコピペして実行してみてください。`members.csv`と同じ階層にPythonファイルを作成して実行するのが簡単です。
<!-- HTMLエスケープされたPythonコード -->
import csv
# --- 私がハマった点①:文字コード指定は絶対! ---
# Windows環境だと、何もしないとShift_JISで開こうとしてエラーになることがあります。
# `encoding='utf-8'` をお守りのように付けておきましょう。
with open('members.csv', mode='r', encoding='utf-8') as f:
# csv.readerにファイルを渡すと、CSVを解析してくれるリーダーオブジェクトが返ってくる
reader = csv.reader(f)
# 1行ずつループで処理できる
for row in reader:
print(row)
# 実行結果:
# ['id', 'name', 'email']
# ['1', '山田太郎', 'taro.yamada@example.com']
# ['2', '鈴木花子', 'hanako.suzuki@example.com']
# ['3', '佐藤次郎', 'jiro.sato@example.com']
どうですか?ターミナルにCSVの内容が表示されましたか?
注目ポイントは、1行が1つのリスト(`[]`で囲まれたやつ)として取得できている点です。`['1', '山田太郎', 'taro.yamada@example.com']` のように、カンマで区切られたデータがリストの各要素になっていますね。
ちょっと解説:`with open(...) as f:`って何?
これはファイルを扱うときの「お作法」です。こう書くことで、`with`のブロックを抜けた時に、Pythonが自動でファイルを閉じてくれます。ファイルを閉じ忘れると、メモリリークなどの思わぬ不具合に繋がるので、必ず`with`を使いましょう!
【私の失敗談①】文字化け地獄と`encoding`
私が最初にこれをやった時、特にWindowsのPCで、コンソールが意味不明な記号(通称"豆腐")だらけになりました。原因は文字コードです。PCはファイルがどの言語のルール(エンコーディング)で書かれているか、教えてあげないと正しく読めません。
解決策は、`open()`の引数に`encoding='utf-8'`を追加すること。`UTF-8`は世界標準の文字コードで、これを使っていれば大体うまくいきます。Webの世界では必須の知識なので、癖にしておきましょう!
基本の「か」:新しいCSVファイルに書き込んでみよう (`csv.writer`)
次はデータの書き込みです。Pythonで作成したリストデータを、新しいCSVファイルとして保存してみましょう。例えば、新しい会員データを`new_members.csv`というファイルに書き出す、みたいなイメージです。
<!-- HTMLエスケープされたPythonコード -->
import csv
# 書き込みたいデータ(リストのリスト)
new_data = [
['4', '高橋四郎', 'shiro.takahashi@example.com'],
['5', '伊藤五月', 'satsuki.ito@example.com']
]
# --- 私がハマった点②:謎の空行には newline='' ---
# mode='w'で書き込みモードに。ファイルがなければ新規作成される。
# newline='' を指定しないと、Windowsでは1行おきに謎の空行が入る!
with open('new_members.csv', mode='w', encoding='utf-8', newline='') as f:
writer = csv.writer(f)
# 1行だけ書き込む場合は writerow
writer.writerow(['id', 'name', 'email']) # ヘッダー行
# 複数行まとめて書き込む場合は writerows
writer.writerows(new_data)
print('new_members.csv を作成しました!')
このコードを実行すると、同じ階層に`new_members.csv`というファイルが作られているはずです。中身を開いてみてください。ちゃんとデータが書き込まれていますよね?
【私の失敗談②】お前は誰だ!?謎の空行と`newline=''`
これも私が半日溶かした問題です。上のコードの`newline=''`を消してWindowsで実行してみてください。どうです?CSVファイルが1行おきに、忌々しい空行で埋め尽くされませんでしたか?
これはOSによる改行コードの扱いの違いが原因で起こる、あるあるな罠です。詳しい説明は長くなるので省きますが(私もAIに聞いて「なるほど、わからん!」ってなりました)、解決策はただ一つ。
CSVを書き込むときは、`open()`に`newline=''`を必ず付ける!
これはPythonの公式ドキュメントにも「csvモジュールを使う場合は、必ず指定してください」と書かれている、超重要なお作法です。もう呪文のように覚えてください。
応用編①:辞書で扱うと、コードが神レベルに読みやすくなる (`DictReader` & `DictWriter`)
基本の`reader`だと、`row[1]`や`row[2]`のように、何番目のデータが何なのか、インデックス番号で管理する必要がありました。これ、列が増えると「あれ、メールアドレスって何番目だっけ…?」ってなりますよね。
そこで登場するのが`DictReader`です!これを使うと、1行のデータを「辞書」の形で取得できます。つまり、`row['name']`や`row['email']`のように、ヘッダー名でデータにアクセスできるようになるんです。天才か?
読み込み: `DictReader`
<!-- HTMLエスケープされたPythonコード -->
import csv
with open('members.csv', mode='r', encoding='utf-8') as f:
# DictReaderを使うだけ!簡単!
reader = csv.DictReader(f)
for row in reader:
# 'name'キーで名前に、'email'キーでメールアドレスにアクセスできる!
print(f"名前: {row['name']}, メール: {row['email']}")
# 実行結果:
# 名前: 山田太郎, メール: taro.yamada@example.com
# 名前: 鈴木花子, メール: hanako.suzuki@example.com
# 名前: 佐藤次郎, メール: jiro.sato@example.com
どうです?`row[1]`より`row['name']`の方が、圧倒的に分かりやすいですよね!これなら後からコードを見返したときも、何をやっているか一目瞭然です。
書き込み: `DictWriter`
読み込みが辞書なら、書き込みも辞書でしたいですよね。もちろん`DictWriter`があります。辞書のリストを用意すれば、それをCSVに書き込めます。
<!-- HTMLエスケープされたPythonコード -->
import csv
# 辞書のリストとしてデータを用意
dict_data = [
{'id': '6', 'name': '渡辺六助', 'email': 'rokusuke.watanabe@example.com'},
{'id': '7', 'name': '中山七海', 'email': 'nanami.nakayama@example.com'}
]
# ヘッダーのリスト(重要!)
fieldnames = ['id', 'name', 'email']
with open('dict_members.csv', mode='w', encoding='utf-8', newline='') as f:
# DictWriterには、ファイルとヘッダー(fieldnames)を渡す
writer = csv.DictWriter(f, fieldnames=fieldnames)
# 最初にヘッダーを書き込むのを忘れずに!
writer.writeheader()
# 辞書のリストをまとめて書き込む
writer.writerows(dict_data)
print('dict_members.csv を作成しました!')
`DictWriter`を使う時の注意点は2つです。
- `csv.DictWriter()`を初期化するときに、`fieldnames`(ヘッダーのリスト)を渡してあげること。
- データを書き込む前に、`writer.writeheader()`でヘッダー行を書き込んであげること。
これを忘れると正しく書き込めないので注意してくださいね!(もちろん私はやらかしました)
応用編②:既存のCSVにデータを追記する
「お問い合わせが来るたびに、会員リストに新しい会員情報を追加したい」そんな時は、ファイルを「追記モード」で開きます。
やり方は超簡単。`open()`の`mode`を`'w'`(write)から`'a'`(append)に変えるだけです。
<!-- HTMLエスケープされたPythonコード -->
import csv
# 追記したい新しい会員データ
new_member = ['8', '吉田八重', 'yae.yoshida@example.com']
# modeを 'a' (append) にするだけ!
# 追記なので、newline='' と encoding='utf-8' は忘れずに。
with open('members.csv', mode='a', encoding='utf-8', newline='') as f:
writer = csv.writer(f)
writer.writerow(new_member)
print('members.csv にデータを追記しました!')
このコードを実行した後、もう一度`members.csv`を開いてみてください。一番下に「吉田八重」さんの情報が追加されているはずです。`DictWriter`で追記する場合は、`writeheader()`を呼び出さないように気をつけてくださいね。でないと、追記するたびにヘッダーが追加されてしまいます。
【動くを体験】ブラウザでCSVをグリグリ動かしてみよう!
さて、ここまでたくさんのコードを見てきました。でも、やっぱり自分で動かして、いじってみるのが一番の近道です。
そこで今回は、ブラウザ上でPythonを動かせる魔法の技術「PyScript」を使って、CSVデータをリアルタイムに操作できるインタラクティブなデモを用意しました!
以下のHTMLコードをまるごとコピーして、`csv_test.html`のような名前でPCに保存してください。そして、そのファイルをWebブラウザで開いてみてください。これだけで、あなたのブラウザがCSVエディタに早変わりします!
<!-- HTMLエスケープされたHTMLコード -->
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Python CSVモジュール 体験デモ</title>
<!-- PyScriptの読み込み -->
<link rel="stylesheet" href="https://pyscript.net/releases/2024.1.1/core.css" />
<script type="module" src="https://pyscript.net/releases/2024.1.1/core.js"></script>
<!-- 簡単なスタイル -->
<style>
body { font-family: sans-serif; background-color: #202124; color: #e8eaed; padding: 2em; line-height: 1.6; }
h1, h2 { color: #8ab4f8; }
textarea, button {
border: 1px solid #5f6368;
background-color: #3c4043;
color: #e8eaed;
border-radius: 4px;
padding: 0.5em 1em;
}
textarea { width: 100%; height: 150px; margin-bottom: 1em; font-family: monospace; }
button { cursor: pointer; margin-right: 1em; }
button:hover { background-color: #5f6368; }
table { border-collapse: collapse; width: 100%; margin-top: 1em; }
th, td { border: 1px solid #5f6368; padding: 8px; text-align: left; }
th { background-color: #3c4043; }
pre { background-color: #1e1e1e; padding: 1em; border-radius: 4px; white-space: pre-wrap; }
</style>
</head>
<body>
<h1>ブラウザで体験!Python CSVモジュール</h1>
<p>下のテキストエリアにCSVデータを入力(または編集)して、「CSVを読み込んでテーブル表示」ボタンを押してください。</p>
<textarea id="csv-input">名前,年齢,都市
山田太郎,32,東京
鈴木花子,28,大阪
佐藤次郎,45,福岡</textarea>
<button py-click="read_csv">CSVを読み込んでテーブル表示</button>
<h2>読み込み結果</h2>
<div id="table-output"></div>
<py-script>
# ここから下がブラウザで動くPythonコードです
import csv
import io # 文字列をファイルのように扱うためのモジュール
from pyscript import document
def read_csv(*args, **kwargs):
# テキストエリアからCSVデータを取得
csv_data = document.querySelector("#csv-input").value
# 文字列をファイルのように扱うためにio.StringIOを使用
# これで、ファイルから読み込むのと同じようにcsvモジュールが使える
csv_file = io.StringIO(csv_data)
# csv.readerで読み込み
reader = csv.reader(csv_file)
# HTMLテーブルを生成
html = "<table>"
try:
# 1行目(ヘッダー)を処理
header = next(reader)
html += "<thead><tr>"
for col in header:
html += f"<th>{col}</th>"
html += "</tr></thead>"
# 2行目以降(データ)を処理
html += "<tbody>"
for row in reader:
html += "<tr>"
for cell in row:
html += f"<td>{cell}</td>"
html += "</tr>"
html += "</tbody>"
except StopIteration:
# データが空だった場合の処理
html += "<tr><td>データがありません</td></tr>"
html += "</table>"
# 結果をDIV要素に表示
output_div = document.querySelector("#table-output")
output_div.innerHTML = html
</py-script>
</body>
</html>
テキストエリアの中身を自由書き換えてボタンを押してみてください。カンマ区切りのテキストが、綺麗なテーブルに変換されるのが分かるはずです。これこそが`csv`モジュールの力です!ぜひ、遊んでみてください。
まとめ:もうあなたはCSVをマスターした!
お疲れ様でした!長旅でしたが、これであなたはPythonを使ったCSV操作の基本から応用まで、完全にマスターしました。最後に、今日学んだ最重要ポイントを振り返っておきましょう。
- 読み込み: 基本は`csv.reader`、列名で扱いたいなら`csv.DictReader`。
- 書き込み: 基本は`csv.writer`、辞書で書きたいなら`csv.DictWriter`。
- 追記: `open()`のモードを`'a'`にする。
- 絶対忘れない2大呪文: 読み書きするなら`encoding='utf-8'`、書き込むなら`newline=''`。
これだけ押さえておけば、実務でCSVを扱う上で困ることはほとんどありません。Webサイトからダウンロードしたデータを分析するもよし、大量のデータを一括でシステムに登録するもよし。あなたのアイデア次第で、活用の幅は無限に広がります。
プログラミングは、こうして一つ一つ「動いた!」という成功体験を積み重ねていくのが上達のコツです。今回の記事が、あなたのその一助となれば、これ以上嬉しいことはありません。
次のステップへ
CSVと同じくらいWeb開発でよく使われるデータ形式に「JSON」があります。API連携など、より高度な開発には必須の知識です。次の記事でマスターして、さらにレベルアップしましょう!
jsonモジュールでJSONデータを扱う方法