csvモジュール

このレッスンでできるようになること。手書きの split をやめて、標準の csv モジュールで家計簿ファイルを読み書きできるようになります。

入門では、カンマ区切りの1行を line.split(",") で分解していました。データが「ノート,200,文具」のように素直なうちは、これで問題ありません。ところが家計簿には「コーヒー, 豆」のように、品名そのものにカンマが入る行がいつか現れます。そのとき split は品名を2つに割ってしまい、金額の位置がずれて集計が壊れます。

この手の面倒は、CSV という形式を作った人たちがとっくに解決しています。値の中にカンマがあるときは、その値をダブルクォートで囲むという決まりです。読む側はクォートの内側のカンマを区切りとして数えません。標準ライブラリの csv モジュールは、この決まりを最初から知っています。

書くときは csv.writer(f) を作り、writerow で1行、writerows でまとめて書きます。クォートが必要な値には、csv 側が勝手に付けてくれます。読むときは csv.reader(f) を作り、for で回すと1行が文字列のリストになって返ってきます。

import csv with open("shishutsu.csv", "w", encoding="utf-8", newline="") as f: writer = csv.writer(f) writer.writerow(["品名", "金額"]) writer.writerow(["コーヒー, 豆", 980]) with open("shishutsu.csv", encoding="utf-8") as f: reader = csv.reader(f) for row in reader: print(row)

注意することが2つあります。1つ目は、書くときの open に newline="" を付けることです。付けないと環境によっては空行が1行おきに混ざります。2つ目は、encoding="utf-8" を必ず書くことです。日本語のデータを扱うので、ここを省くと後で文字化けします。

もう1つ覚えておきたいのが next(reader) です。1行目の見出し行を1回だけ取り出して、残りをデータとして回すときに使います。csv.reader が返す値はすべて文字列なので、金額を足すときは int(row[1]) のように数値へ戻す必要があります。

要件

  1. csv.writer で見出し行を含む rows をすべて kakeibo_csv.csv に書き出す
  2. 書き出しの open には encoding="utf-8" と newline="" を付ける
  3. csv.reader で読み直し、next で見出し行を読み飛ばす
  4. データ行ごとに「品名 金額」を空白区切りで表示する
  5. 最後に「合計 13180」の形で合計金額を表示する

入出力例

出力: "ノート 200 コーヒー,980 定期券 12000 合計 13180 "

ヒント

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部
main.py
学習モード

メモ

csvモジュール

⌘S で保存