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

テキストストリームオブジェクト

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

公開日

広告