Pythonで2つの辞書リストを比較する方法|差分の出力とPandas活用術
この記事では、Pythonで2つの「辞書のリスト」を比較し、両者の差分を出力する方法を解説します。
ここで紹介する比較方法では、辞書内のキーと値の両方が比較対象になります。
また、Pythonで辞書のリスト同士を比較する場合、要素の並び順は結果に影響しません。キーと値の組み合わせが同じであれば、順序が異なっていても等しいものとして扱われます。
Pythonで辞書のリストを比較する基本方法
if __name__ == '__main__':
list_1 = [
{'id': '123-abc', 'name': 'Mike', 'age': 40},
{'name': 'John', 'age': 34, 'id': '123-efg'},
{'age': 32, 'id': '123-xyz', 'name': 'Aly'}
]
list_2 = [
{'name': 'Mike', 'id': '123-abc', 'age': 40},
{'id': '123-efg', 'age': 34, 'name': 'John'},
{'id': '123-xyz', 'name': 'Aly', 'age': 32}
]
assert [i for i in list_1 if i not in list_2] == []
上記のコードでは、list_1 と list_2 は等しいと判定されます。つまり、両方のリストに含まれる各辞書が同じ項目(キーと値)を持っているということです。各辞書内での要素の並び順は問われません。
このアプローチのポイントは、リスト内包表記を使って「list_1 のうち list_2 に存在しない要素」を抽出している点です。結果が空リストであれば、2つのリストは一致していることになります。
辞書のリストを比較して差分を出力する
単に一致・不一致を判定するだけでなく、「どの辞書が異なっているのか」を出力することもできます。
例えば、次のように記述します。
if __name__ == '__main__':
list_1 = [
{'id': '123-abc', 'name': 'Mike', 'age': 40},
{'id': '123-efg', 'name': 'John', 'age': 24},
{'id': '123-xyz', 'name': 'Aly', 'age': 35}
]
list_2 = [
{'id': '123-abc', 'name': 'Mike', 'age': 40},
{'id': '123-efg', 'name': 'Jon', 'age': 24},
{'id': '123-xyz', 'name': 'Aly', 'age': 32}
]
for i in list_1:
if i not in list_2:
print(i)
実行結果:
{'id': '123-efg', 'name': 'John', 'age': 24}
{'id': '123-xyz', 'name': 'Aly', 'age': 35}
この例では、list_1 に含まれていて list_2 には存在しない辞書だけが出力されます。'name' や 'age' の値が少しでも違えば、別の辞書として扱われる点に注意してください。
関数化して再利用しやすくする
同じ処理を関数としてまとめると、次のように書けます。
def compare_two_lists(list1: list, list2: list) -> bool:
"""
2つのリストを比較し、差分をログに出力する。
:param list1: 1つ目のリスト
:param list2: 2つ目のリスト
:return: 差分がない場合は True
"""
diff = [i for i in list1 + list2 if i not in list1 or i not in list2]
result = len(diff) == 0
if not result:
print(f'{len(diff)}件の差分があります:\n{diff[:5]}')
return result
この関数は、両方のリストを結合した上で「どちらか一方にしか存在しない要素」を差分として検出します。差分がある場合は、その件数と内容(最大5件)を出力し、戻り値として一致の可否を bool 型で返します。
Pandas DataFrameを使って2つのリストを比較する
より大規模なデータや複雑な条件で比較したい場合は、PandasのDataFrameを活用すると便利です。以下のコードは、2つのリストをDataFrameに変換して差分を求める例です。
from pandas import DataFrame
import pandas as pd
def compare_two_lists(list1: list, list2: list) -> bool:
"""
2つのリストを比較し、差分をログに出力する。
:param list1: 1つ目のリスト
:param list2: 2つ目のリスト
:return: 差分がない場合は True
"""
df1 = pd.DataFrame(list1)
df2 = pd.DataFrame(list2)
diff = dataframe_difference(df1, df2)
result = len(diff) == 0
if not result:
print(f'{len(diff)}件の差分があります:\n{diff.head()}')
return result
def dataframe_difference(df1: DataFrame, df2: DataFrame) -> DataFrame:
"""
2つのDataFrame間で異なる行を検出する。
:param df1: 1つ目のDataFrame
:param df2: 2つ目のDataFrame
:return: 差分となる行のみを含むDataFrame
"""
comparison_df = df1.merge(df2, indicator=True, how='outer')
diff_df = comparison_df[comparison_df['_merge'] != 'both']
return diff_df
この方法では、merge() メソッドに indicator=True を指定することで、各行が「片方のDataFrameにのみ存在するのか」「両方に存在するのか」を示す _merge 列が自動的に追加されます。この列が 'both' 以外の行、すなわちどちらかにしか存在しない行を抽出すれば、それが2つのリスト間の差分となります。
データ量が多い場合や、差分行の一覧を表形式で確認したい場合には、このPandasを使った手法が特に有効です。
-
Pythonで2つのリストの要素を加算する方法【append・map・zip】
Pythonでは、2つのリストを「足し合わせる」ことで、両方のリストの要素を含む新しいリストを作成できます。ここでいう「追加」とは、リスト同士を単純に連結するのではなく、同じインデックス位置にある要素同士を加算することを指します。本記事では、代表的な3つの手法をコード例とともに解説します。なお、いずれの方法でも2つのリストは同じ長さである必要がある点に注意してください。1. append()を使う方法append()メソッドを使うと、片方のリストの要素を別のリストへ追加できます。ここでは空の新しいリストを用意し、forループで各インデックスの要素を加算しながら順に追加していきます。コード例Li
-
Pythonで2つの辞書を1つの式でマージする方法
Pythonで2つの辞書を1つに結合(マージ)したい場面はよくあります。ここでは、代表的な2つの方法をサンプルコード付きでわかりやすく解説します。 update()メソッドを使う方法 組み込みの辞書(dict)クラスにはupdate()メソッドが用意されています。このメソッドは、引数として渡した辞書オブジェクトの要素を、呼び出し元の辞書オブジェクトに統合します。なお、元の辞書そのものが更新される点に注意してください。 >>> a = {1:a, 2:b, 3:c} >>> b = {x:1, y:2, z:3} >>> a.updat