Pythonでcsv形式の文字列データをパースする

Pythonのcsvモジュールで、文字列データをパースしてリストに変換します。

目次

  1. csvのreaderに文字列を渡してもパースできない
  2. テキストストリームを通してcsvモジュールに渡す
  3. 試してみた
  4. 主なクラスとメソッド

csvのreaderに文字列を渡してもパースできない

CSVデータがファイルになっているのであれば、ファイルを開いてcsvモジュールのreaderにファイルオブジェクトを渡せば、パースしてリストにしてくれます。

ところが、プログラム内の文字列を渡すとエラーになります。

プログラム内にテキストがあるなら、splitなどを使って自力でパースできないこともありませんが、例外チェックなどもあって面倒です。

そこで、ストリームを使ってプログラム内の文字列をcsvモジュールにパースしてもらいます。

テキストストリームを通してcsvモジュールに渡す

手順

  1. テキストストリームを作成
  2. テキストストリームに文字列を書き込み
  3. カーソルをテキストストリームの先頭に移動
  4. 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 テキストストリームオブジェクト

テキストストリームを閉じます。

広告

PythonでCSVカテゴリの投稿