はじめに
辞書型のリストのパラメータ同士を比較し、差分を求める必要があったので記しておく。
パラメータの形式は、下記のようなIDを持った辞書型のリスト。
dl = [
{'id': 'test001', 'value': '111'},
{'id': 'test002', 'value': '222'},
{'id': 'test003', 'value': '333'}
]
コード
test.py
dl1 = [
{'id': 'test001', 'value': '111'},
{'id': 'test002', 'value': '222'},
{'id': 'test003', 'value': '333'}
]
dl2 = [
{'id': 'test002', 'value': '222'}
]
s1 = set(x['id'] for x in dl1)
s2 = set(x['id'] for x in dl2)
diff = [{'id': x} for x in s1 - s2]
result = [d for x in diff for d in dl1 if x['id'] == d['id']]
結果
[{'id': 'test001', 'value': '111'}, {'id': 'test003', 'value': '333'}]
解説
- 辞書型のリストからIDのみを抜き出し、set型に変換
s1 = set(x['id'] for x in dl1)
s2 = set(x['id'] for x in dl2)
set型に変換してから比較することで差分を得られるが、
内容が辞書型である場合、hashableでないためにエラーになる。
その為、辞書の中でユニークな値であるIDを抜き出しset型に変換。
- IDの差分を得る
diff = [{'id': x} for x in s1 - s2]
IDの差分を取得。
- IDで合致する要素を抜き出し、辞書型のリスト同士の差分の結果とする
result = [d for x in diff for d in dl1 if x['id'] == d['id']]
取得したIDのリストと辞書型のリストをループさせ、
ID同士で比較して合致したものを抜き出す。
下記はワンライナーじゃないバージョン
result = []
for x in diff:
for d in dl1:
if x['id'] == d['id']:
result.append(d)
おわりに
一撃で差分を取るスマートな方法ないですかね。