Pythonで複数のリストに共通する・しない要素とその個数を取得
Pythonで複数のリストから共通する要素・しない要素を抽出・削除するには、各リストを集合set
に変換し集合演算を行う。
集合set
および集合演算についての詳細は以下の記事を参照。
一つのリストの重複する要素を抽出したい場合は以下の記事を参照。
本記事のサンプルコードではリストを使うが、タプルでも同様の処理が可能。
複数のリストから共通する要素を抽出
複数のリストに共通する要素はset
に対する&
演算子で抽出できる。なおset
は順序を持たないので、どういう順番で出力されるかは不定。
l1 = ['a', 'b', 'c']
l2 = ['b', 'c', 'd']
l3 = ['c', 'd', 'e']
l1_l2_and = set(l1) & set(l2)
print(l1_l2_and)
# {'c', 'b'}
print(type(l1_l2_and))
# <class 'set'>
set
をリストlist
に変換したい場合はlist()
を使う。上述のようにset
に変換すると順序は保持されないので、再度リストに戻したときに元のリストの順序と変わる場合がある(偶然同じ順序になることはある)。
l1_l2_and_list = list(l1_l2_and)
print(l1_l2_and_list)
# ['c', 'b']
print(type(l1_l2_and_list))
# <class 'list'>
個数はlen()
で取得可能。
print(len(l1_l2_and))
# 2
3個以上のリストの場合も同様。
print(set(l1) & set(l2) & set(l3))
# {'c'}
リストから他のリストと共通する要素を削除
あるリストから他のリストと共通(重複)する要素を削除するにはset
に対して-
演算子を使う。削除した結果、空のset
が返される場合もある。
l1 = ['a', 'b', 'c']
l2 = ['b', 'c', 'd']
l3 = ['c', 'd', 'e']
print(set(l1) - set(l2))
# {'a'}
print(set(l2) - set(l1))
# {'d'}
print(set(l2) - set(l1) - set(l3))
# set()
上述のように、リストに戻したり個数を取得する場合はlist()
, len()
を使う。例は省略。以後も同じ。
複数のリストから共通しない要素を抽出
set
に対する対称差集合(二つの集合のどちらか一方にのみ含まれる要素の集合)は^
演算子で取得できる。
l1 = ['a', 'b', 'c']
l2 = ['b', 'c', 'd']
l3 = ['c', 'd', 'e']
print(set(l1) ^ set(l2))
# {'d', 'a'}
元のリストが3個の場合に^
演算子を使うと、すべてのリストに共通する要素も含まれるので注意。
print(set(l1) ^ set(l2) ^ set(l3))
# {'c', 'a', 'e'}
いずれかのリストにのみ含まれる要素を抽出したい場合は、すべてのリストを連結したリストから個数が1個の要素を抽出する方法がある。リスト内包表記および要素の個数を取得するメソッドcount()
を使う。
- 関連記事: Pythonリスト内包表記の使い方
- 関連記事: PythonのCounterでリストの各要素の出現個数をカウント
set()
を使うことで、同じ値の要素の個数を繰り返しカウントする無駄を防ぐことができる。
l_all = l1 + l2 + l3
print(l_all)
# ['a', 'b', 'c', 'b', 'c', 'd', 'c', 'd', 'e']
print(set(l_all))
# {'c', 'd', 'a', 'b', 'e'}
print([x for x in set(l_all) if l_all.count(x) == 1])
# ['a', 'e']
なお、この方法だと元のリストが重複する要素を持っていた場合、その要素も除外されてしまう。
l1_dup = ['a', 'a', 'b', 'c']
l_dup_all = l1_dup + l2 + l3
print([x for x in set(l_dup_all) if l_dup_all.count(x) == 1])
# ['e']
最初に各リストごとに重複した要素を削除してユニークな要素のみのリストにしてから処理すれば、各リストにのみ含まれる要素を抽出可能。
l_unique_all = list(set(l1_dup)) + list(set(l2)) + list(set(l3))
print(l_unique_all)
# ['c', 'b', 'a', 'c', 'd', 'b', 'c', 'd', 'e']
print([x for x in set(l_unique_all) if l_unique_all.count(x) == 1])
# ['a', 'e']
複数のリストからユニークな要素を抽出
複数のリストの要素から重複を取り除きユニークな(一意な)値の要素を抽出したい場合は、リストをすべて足し合わせてから集合set
に変換する。
l1 = ['a', 'b', 'c']
l2 = ['b', 'c', 'd']
l3 = ['c', 'd', 'e']
print(set(l1 + l2))
# {'c', 'd', 'b', 'a'}
print(set(l1 + l2 + l3))
# {'c', 'd', 'a', 'b', 'e'}
元のリストの順序を保持したい場合は以下の記事を参照。