Pythonのデータ管理
pythonはデータdictが非常に使いやすく、ある程度のデータの固まりを扱うときにわざわざ専用のクラスやc言語のstructのようなものを作らなくても、dictやdictを収容したlistなどで十分代用できてしまう。
なのだけれど、よく以下のどちらの構造を取るかで迷うことがある。
- dictで表現する
- listでdictを収容して表現する
例えば、yamlで例を書いてみるとこんな感じ。
dictで表現
’0001':
id: '0001'
name: user01
'0002':
id: '0002'
name: user02
listで表現
- id: '0001'
name: user01
- id: '0002'
name: user02
APIでデータ引っこ抜く系だと後者で見かけることが多い気もするけれど、prosとconsをまとめてみる。
dict表現の特徴
pros
データの検索性が良い
data[<id>]あるいはdata.get(<id>, None)などとすれば、ほしいデータを一発で引き抜ける。
listだと、1つ1つのデータを調べて、idがほしい値に一致するものを探さないといけない。
cons
keyにできる共通の要素が必要
keyを設定するために、全部のデータが共通で持ち、かつ一意性のある情報が必要。
例のようにidみたいな重複しない一位識別子があるデータならいいけれど、nameだけ(同姓同名があり得る)というようなケースに対応できない。
また、keyは1つしか設定できないため、一位識別子が複数ある場合にどっちを使う、、?という問題にぶつかる。
順序を保持できない
「最新のもの1件を引き抜きたい」という用途に使うことができない。
list表現の特徴
pros
データの構造を気にせず格納できる
dictのkeyのように、全データが共通かつ一位的に持たないといけないデータが無いので、自由なフォーマットで格納できる。
順序を保持できる。
cons
検索性
処理自体はそう重くないのだろうけれど、コードが野暮ったくなる。
まとめ
データがしっかりフォーマットに則っていて、わかりやすい一意識別子があるときはdict。
それ以外はlistかな。。
listのときは検索性が課題になる。
forループ回してヒットするものを見つけるか、並べ直すか。
...まぁそりゃ重複は考慮できんけど。
genkey = labmda x: x.get('id', str(x))
dict_data = dict([(genkey(x), x) for x in data])
ん?あ、これでいいのか。
search_result = [x for x in data if isinstance(x, dict) and <key> == x.get('<key>', None)])
気持ちはちょっと悪いけど、、処理不可が気にならんならこれで検索すりゃいいから、listのほうが無難、、なのかな。。
なんか気持ち悪いけど。