Excelで作成したCSVファイルをPythonのcsvモジュールで読み込む

もう何年もPythonCSVファイルを扱うのはやってきているので今更な感じではあるが、過去に記事を書いてなかったので書いとく。
みんな相変わらずExcel大好きだよね。実際便利だし。

CSVファイルを作成する

Excelで適当に入力してファイルの種類をCSVにして保存。今回1行目はヘッダーとして使うので、半角英数にしています。

item,cost,amount
りんご,100,4
みかん,50,3
バナナ,200,1


日本語のWindows環境の場合、保存したファイルの文字コードはShiftJIS(cp932)になります。
このファイルをPythonから読み込みます。

Pythoncsv.DictReaderを使って読み込む

csv.DictReaderを使うと読み込んだ結果を辞書で得ることができます。その際辞書のキーはCSVファイルの1行目の内容が使われます。
DictReaderそのままでは、Unicodeへのデコードが行われないので、継承してデコードを行なうクラスを作成しました。
Pythonのバージョンは2.7。

test.py

amountとcostの列は数値に変換して計算に使っています。

# coding: utf-8
import csv

DATAFILE = 'data.csv'


class UnicodeDictReader(csv.DictReader):
    """値をcp932でデコードするDictReader
    """

    def __init__(self, f, fieldnames=None, restkey=None, restval=None,
                 dialect="excel", encoding="cp932", *args, **kwds):
        csv.DictReader.__init__(
            self, f, fieldnames, restkey, restval, dialect, *args, **kwds)
        self.encoding = encoding

    def decode(self, value):
        return value and value.decode(self.encoding) or value

    def next(self):
        d = csv.DictReader.next(self)
        for key in d:
            d[key] = self.decode(d[key])
        return d


def main():
    total = 0
    with open(DATAFILE) as csvfile:
        reader = UnicodeDictReader(csvfile)
        for record in reader:
            # 値を数値で取得
            cost = int(record['cost'])
            amount = int(record['amount'])
            # アイテムごとの金額
            item_total = cost * amount
            # 全体の合計額
            total += item_total
            print(u"%s | %s %d 円 * %d 個 = %d 円" % (
                reader.line_num, record['item'], cost, amount, item_total))
    print(u"合計 %d 円" % total)

if __name__ == '__main__':
    main()
実行結果
>python test.py
2 | りんご 100 円 * 4 個 = 400 円
3 | みかん 50 円 * 3 個 = 150 円
4 | バナナ 200 円 * 1 個 = 200 円
合計 750 円