Edited at

python2.7.3のcsvモジュールを使う時の文字エンコード

More than 5 years have passed since last update.

日本語の値を含むcsvファイルをPythonのcsvモジュールを使って読み込みました

以下の条件での問題とその解決法です


  • 読み込むcsvファイルの文字エンコード: UFT-8


  • sys.getdefaultencoding()で得られる文字エンコード: ascii

  • スクリプトの文字エンコード: UTF-8

まず普通に読み込みます

csvの形式は

整数,文字列の形としておきます

class data:

def __init__(self, id, name):
self.id = id
self.name = name

import csv

csvfile = open(filename)
reader = csv.reader(csvfile)
rows = [data(row[0], row[1]) for row in reader]

これですべての行のデータを読み込めました

次に、 任意の日本語文字列を名前に含むデータ を抽出します

text = raw_input()

result = [row for row in rows if text in row.name]

ここで問題がおきます。raw_input()で得られる文字列は unicode型 です

ところがdata.nameで得られるのはcsv.readerが読み取った utf-8のstr型 なのです

当然比較はできませんので、 if text in row.nameのところでエラーが発生します。


じゃあどうするか

解決方法は、


  • すべてunicodeにする

  • すべてUTF-8のstrにする

の2つが考えられると思いますが、何かと扱いやすいのはunicodeなので今回は前者にします。

この場合修正が必要なのは、

rows = [data(row[0], row[1]) for row in reader]

です。ここをこうします

rows = [data(row[0], row[1].decode('utf-8')) for row in reader]

str#decodeは任意の文字エンコードで、str型をunicode型に変換します。今回は元がutf-8のstrなので、utf-8でデコードしてunicodeに変わりました。

元のcsvファイルの文字エンコードによってデコードは変える必要があります(当然ですね)

これでunicode同士で比較ができるようになりました。めでたしめでたし

Windowsでpythonいじってるとこういう文字エンコードの問題によくぶつかりますね。