nikkie-ftnextの日記

イベントレポートや読書メモを発信

mapで変換! csvモジュールで読み込んだ行から、リスト/辞書/タプル/名前付きタプル/データクラス(のインスタンス)を作る

はじめに

わりぃ、おれ、死んだ、nikkieです1

CSV形式のファイルを読み込んで、行を各種データ型に変換する方法を一覧にしていきます!
ドキュメントを見ていたら「これ、どんなデータ型にも変えられるんじゃないか💡」と着想を得たんですよ

目次

本記事の背景

以下のツイートがきっかけです。

ポイントは組み込み関数map

この記事の主役はmapです!
https://docs.python.org/ja/3/library/functions.html#map
map(function, iterable)で「function を iterable の全ての要素に適用して結果を生成」します(イテレータが返ります)。

namedtupleのドキュメントを読んでいて知りました2

CSVファイルを読み込んでデータ型に変換

以下のsome.csvを読み込みます。

name,price
apple,1000
banana,500

(2023/04/21 追記)Python 3.10.9で動作確認しました(追記終わり)

list(リスト)

csv.readerで読み込むだけです(きっかけとなったツイートの話ですね)。

dict(辞書)

csv.DictReaderで変換できます3

tuple(タプル)

組み込み関数mapの出番!
csv.readerが返す要素のリストをmapでタプルに変換しちゃいましょう。
csv.readerインスタンスforと一緒に使えるのでイテラブル、つまり、mapのiterable引数に渡せます!

名前付きタプル

名前付きタプルには以下の2つがあると思います。
どちらもmapで変換できます。
_makeメソッド4がミソですね

collections.namedtuple

https://docs.python.org/ja/3/library/collections.html#collections.namedtuple

typing.NamedTuple

https://docs.python.org/ja/3/library/typing.html#typing.NamedTuple

データクラスのインスタンス

https://docs.python.org/ja/3/library/dataclasses.html#dataclasses.dataclass

いろいろな実装があると思います。
組み込み関数mapのドキュメントでitertools.starmapを知りました。

関数の入力が引数タプルとして単一のイテラブルの形で整理されている場合は、 itertools.starmap() を参照してください。

https://docs.python.org/ja/3/library/itertools.html#itertools.starmap

そこで今回は行をリストとして読み込み(csv.reader)、starmapを使うことにしました。
データクラスにはインスタンスを作成するためのクラスメソッド(=ファクトリ用途)を持たせています5

csv.readerの返す要素(リスト)をstarmapでアンパックしてファクトリメソッドに渡すので、データクラスのインスタンスに変換されます。

終わりに

CSVの行を各種データ型に変換する方法を一覧にしました。
map(やitertools.starmap)が大活躍!
リスト・辞書・タプル・名前付きタプル・データクラスとなんでもござれです🙌

全ては偶然namedtupleのドキュメントでmapを知ったことによります。
この一覧はCSVファイルに限らず利用できると思うので、今後Pythonを書くのがますます楽しみになってきています!


  1. 名前付きタプルは csv や sqlite3 モジュールが返すタプルのフィールドに名前を付けるときにとても便利です:」のところのコード例にmapが使われています!
  2. 最近ちょうど取り上げました。
  3. https://docs.python.org/ja/3/library/collections.html#collections.somenamedtuple._make
  4. ファクトリメソッドはクラスメソッドでもスタティックメソッドでもよいと考えています(今のnikkieにこだわりはありません)