はじめに
ういっす✌️ nikkieです。
先日、CSVファイルの行を種々のデータ型に変換する実装を一覧にしました。
その中でデータクラスのインスタンスへの変換について、いろんなやり方があると気づいたので一覧にします。
目次
前提
CSV形式のファイルを読み込んで、行を各種データ型に変換する題材を引き続き考えていきます。
このエントリでは、CSV形式の行からデータクラスのインスタンスを作る方法に集中します。
読み込むCSV(some.csv
)は以下です。
name,price apple,1000 banana,500
Python 3.10.9で動作確認しました
csv.reader
が返す要素(リスト)から作る
CSVファイルの行はリストで表されます。
['apple', '1000']
map
を使う
データクラスのインスタンスを作るメソッド(ファクトリメソッド)をcsv.reader
が返すリスト(行)1つ1つにmap
で適用します。
https://docs.python.org/ja/3/library/functions.html#map
ファクトリメソッドは行を表すリストを受け取ります(1引数)。
リストをまずアンパックしてから、インスタンスを返す実装にしました。
itertools.starmap
を使う
こちらは先日のエントリで示したコードと同一です。
starmap
はmap
と違って、シーケンスをアンパックした状態でファクトリメソッドに渡します(位置引数渡し)。
https://docs.python.org/ja/3/library/itertools.html#itertools.starmap
つまり、ファクトリメソッドはシーケンス1つを受け取る引数ではなく、シーケンスの要素数だけの引数(ここでは2引数)を持ちます。
csv.DictReader
が返す要素(辞書)から作る
CSVファイルの行は辞書で表されます。
{'name': 'apple', 'price': '1000'}
map
を使う
ファクトリメソッドは行を表す辞書を受け取ります(1引数)。
キーを使って辞書の値にアクセスしてインスタンスを作ります。
「書きやすくなるかな」とTypedDict
も使ってみました1。
VS Codeを使っているのですが、辞書のキーがサジェストされるのはありがたいですね。
itertools.starmap
相当を自作して使う
csv.reader
(行がリスト)のときのstarmap
のように、行が辞書のときのstarmap的なものを自作しました。
辞書をアンパックしてキーワード引数として渡してくれるstarmapです(命名doublestarmap
)。
どなたか実装していそうですが、調べきれなかったので、starmap
をもとに自作しました。
doublestarmap
を使うと、ファクトリメソッドは(辞書を受け取る1引数ではなく、)辞書の長さだけの引数を持ちます。
終わりに
CSVファイルの行からデータクラスのインスタンスを作る方法を洗い出しました。
データクラスのインスタンスを作るメソッドの引数の数に注目すると
- 1引数:行を表すリストや辞書
- 組み込み関数
map
と使う
- 組み込み関数
- 複数の引数(行に含まれる要素と同じだけの引数)
- リストの場合は
itertools.starmap
を使う - 辞書の場合はstarmap相当の関数を自作した(
doublestarmap
)
- リストの場合は
となりました。
map
とstarmap
の違いもつかめたように感じます。