日本語の値を含む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いじってるとこういう文字エンコードの問題によくぶつかりますね。