PythonでExcelを上手に読む
PythonでExcelを読むには、http://pypi.python.org/pypi/pyExceleratorかhttp://pypi.python.org/pypi/xlwtを使うんですが、このpyExceleratorのパース結果が、Excel向きのメソッドのあるオブジェクトじゃなくて、リストとタプルと辞書だけでできていたりして、きれいなんだけど、逆にOOPなPGには扱いにくかったりします。
[ ('Sheet1', {(0,0):1, (1,0):2, (2,0):3, (1,0):4, ... }), ('Sheet2', { ... }), ... ]
こんな感じ。
手続き主体の人が何も考えずに書くと、こんなプログラムになるんじゃないかなと思うサンプル。
import pyExcelerator # シート名をキーにした辞書にデータを入れた book を作る sheets = pyExcelerator.parse_xls("test.xls") book = dict() for name,sheet in sheets: book[name] = sheet # Sheet1を取り出して sheet1 に格納。該当なければ空 if 'Sheet1' in book.keys(): sheet1 = book['Sheet1'] else: sheet1 = {(0,0):0} # 列と行の最大を得る maxcols = 0 maxrows = 0 for col,row in sheet1.keys(): if col > maxcols: maxcols = col if row > maxrows: maxrows = row # 行、列でループ for i in range(maxrows + 1): for j in range(maxcols + 1): if sheet1.has_key((i, j)): print "[%d,%d] = %s" % (i, j, sheet1[(i,j)]) else: print "[%d,%d] = %s" % (i, j, None)
ああ面倒。でも、上手に書くと、こんな感じ。
import pyExcelerator book = dict(pyExcelerator.parse_xls("test.xls")) # 本 sheet1 = book.get('Sheet1', {(0,0):0}) # シート maxcols,maxrows = map(max, zip(*sheet1.keys())) # 最大列/行 # ループ for i in range(maxrows + 1): for j in range(maxcols + 1): print "[%d,%d] = %s" % (i, j, sheet1.get((i,j), None))
dict関数は、実は、[(key, value), (key, value), ...]のようなシーケンスから辞書を作れるんですね。
で、辞書オブジェクトはあえてgetメソッドを使うことで、キーがないというエラーにならず、しかも、キーがなかったときのデフォルト値を指定できる。
あと、zip関数をうまく使うと、
zip((1,2,3), (4,5,6)) # キーリスト、バリューリスト # => ((1,4), (2,5), (3,6)) キーバリューペア zip((1,2), (3,4), (5,6)) # キーバリューペア # => ((1,3,5),(2,4,6)) キーリスト、バリューリスト
こんな感じで転置できるので、(列,行)という形式のキーリストからワンライナーで最大列と最大行が得られます。
これで、Excelを直で読むプログラムがさっさと書き始められます。