Pythonでcsv形式の文字列データをパースする
Pythonのcsvモジュールで、文字列データをパースしてリストに変換します。
目次
csvのreaderに文字列を渡してもパースできない
CSVデータがファイルになっているのであれば、ファイルを開いてcsvモジュールのreaderにファイルオブジェクトを渡せば、パースしてリストにしてくれます。
ところが、プログラム内の文字列を渡すとエラーになります。
プログラム内にテキストがあるなら、splitなどを使って自力でパースできないこともありませんが、例外チェックなどもあって面倒です。
そこで、ストリームを使ってプログラム内の文字列をcsvモジュールにパースしてもらいます。
テキストストリームを通してcsvモジュールに渡す
手順
テキストストリームを作成
テキストストリームに文字列を書き込み
カーソルをテキストストリームの先頭に移動
csvモジュールでテキストストリームを読み取り
テキストストリームを一時ファイルの代わりに使うわけですね。
試してみた
5,7,5,7,7
難波津に,咲くやこの花,冬ごもり,今を春べと,咲くやこの花
花の色は,うつりにけりな,いたづらに,わが身世にふる,ながめせしまに
千早ぶる,神代もきかず,龍田川,からくれなゐに,水くくるとは
こういうCSVデータがプログラム内にあったとして、これをcsvモジュールでパースしてリストにし、pprintで表示してみます。
import io
import csv
import pprint
# テスト用文字列
csv_string = '5,7,5,7,7\n難波津に,咲くやこの花,冬ごもり,今を春べと,咲くやこの花\n花の色は,うつりにけりな,いたづらに,わが身世にふる,ながめせしまに\n千早ぶる,神代もきかず,龍田川,からくれなゐに,水くくるとは\n'
# テキストストリームを作成して書き込み
f = io.StringIO()
f.write(csv_string)
f.seek(0)
# csvモジュールで読み出し
csv_reader = csv.reader(f)
read_data = [row for row in csv_reader]
# テキストストリームを閉じる
f.close()
pprint.pprint(read_data)
実行すると、こう表示されます。
[['5', '7', '5', '7', '7'],
['難波津に', '咲くやこの花', '冬ごもり', '今を春べと', '咲くやこの花'],
['花の色は', 'うつりにけりな', 'いたづらに', 'わが身世にふる', 'ながめせしまに'],
['千早ぶる', '神代もきかず', '龍田川', 'からくれなゐに', '水くくるとは']]
リストに変換できました。
主なクラスとメソッド
StringIOクラス
f = io.StringIO([initial_value], [newline])
変数 |
型 |
内容 |
---|---|---|
initial_value |
str |
省略可。ストリームのバッファの初期値。 |
newline |
str |
省略可。既定値は¥n。改行コード。 |
f |
object |
テキストストリームオブジェクト |
テキストストリームオブジェクトを作成します。
writeメソッド
c = f.write(s)
変数 |
型 |
内容 |
---|---|---|
f |
object |
テキストストリームオブジェクト |
s |
str |
ストリームに書き出す文字列 |
c |
int |
書き出した文字数 |
テキストストリームに文字列を書き出し、書き出された文字列を返します。
seekメソッド
f.seek(offset, [whence])
変数 |
型 |
内容 |
---|---|---|
f |
object |
テキストストリームオブジェクト |
offset.int |
ストリームの位置 |
|
whence |
省略可。既定値はSEEK_SET。 |
offsetで指定した位置にストリーム位置を変更します。
whenceがio.SEEK_SETのときにoffsetを0にすると、ストリームの先頭に移動します。
whenceをio.SEEK_ENDにしてoffsetを0にすると、ストリームの終端に移動します。
closeメソッド
f.close()
変数 |
型 |
内容 |
---|---|---|
f |
object |
テキストストリームオブジェクト |
テキストストリームを閉じます。
公開日
広告