Pythonで2つのリストを比較する方法
はじめに
Pythonでプログラミングをしたり学んだりする際、2つ以上のリストが等しいかどうかを判定する必要がある場合があります。リストを等価に比較する際には、リストの長さが同じかどうか、およびリスト内の各アイテムが等しいかどうかを確認します。異なる長さのリストは決して等しくありません。
この記事では、リストを比較するための以下のPythonの機能の使い方について説明しています。
- sort() method or the sorted() function with the == operator
- set() function with the == operator
- reduce() and map() functions with the == operator
- collection.Counter() class with the == operator
- list comprehension
リストを比較するために、sort()メソッドまたはsorted()関数を使用する。
リストを等しいかどうか比較するために、sort()メソッドまたはsorted()関数を使用できます。sort()メソッドはリストをその場でソートし、一方、sorted()関数は新しいリストを返します。ソート後、同じアイテムを同じインデックス位置に持つリストは等しくなります。==演算子は、リストをアイテムごとに比較します(要素ごとの比較)。
元のリストアイテムの順序は重要ではありません。なぜなら、リストは比較前に並べ替えられるからです。
Note
ソート() メソッドの例
以下の例は、リストをソートして比較するためにsort()メソッドを使用する方法を示しています。
l1 = [10, 20, 30, 40, 50]
l2 = [20, 30, 50, 40, 70]
l3 = [50, 10, 30, 20, 40]
l1.sort()
l2.sort()
l3.sort()
if l1 == l2:
print ("The lists l1 and l2 are the same")
else:
print ("The lists l1 and l2 are not the same")
if l1 == l3:
print ("The lists l1 and l3 are the same")
else:
print ("The lists l1 and l3 are not the same")
出力は次の通りです。
The lists l1 and l3 are the same The lists l1 and l2 are not the same
以下の例のコードでは、まずそれぞれのリストをソートし、l1とl3を比較して結果を出力し、次にl1とl2を比較して結果を出力します。
sorted()関数の例
次の例は、sorted()関数を使用してリストをソートして比較する方法を示しています。
l1 = [10, 20, 30, 40, 50]
l2 = [20, 30, 50, 40, 70]
l3 = [50, 10, 30, 20, 40]
l1_sorted = sorted(l1)
l2_sorted = sorted(l2)
l3_sorted = sorted(l3)
if l1_sorted == l2_sorted:
print ("The lists l1 and l2 are the same")
else:
print ("The lists l1 and l2 are not the same")
if l1_sorted == l3_sorted:
print ("The lists l1 and l3 are the same")
else:
print ("The lists l1 and l3 are not the same")
出力は以下の通りです。
The lists l1 and l3 are the same The lists l1 and l2 are not the same
以下の例のコードは、各リストのソートされたバージョンを返し、l1とl3を比較して結果を出力し、次にl1とl2を比較して結果を出力します。
リストを比較するためにreduce()関数とmap()関数を使う
Pythonのmap()関数とfunctools.reduce()関数を使うと、2つのリストのデータ項目を比較することができます。これらを組み合わせて使用すると、map()関数は与えられた関数をすべての要素に適用し、reduce()関数は関数を連続的に適用することを保証します。
map()関数は関数とイテラブルを引数として受け取ります。map()関数は与えられた関数をイテラブルの各要素に適用し、結果としてmapオブジェクト(イテレータ)を返します。
functools.reduce()関数は、関数とイテラブルを引数として受け取ります。functools.reduce()関数は、与えられた関数をイテラブルのすべての要素に再帰的に適用します。最初に、functools.reduce()は関数を最初の要素と2番目の要素に適用して結果を返し、その後、結果と3番目の要素に関数を適用し、リストの要素がなくなるまで続けます。
組み合わせて使うと、map()関数は与えられた関数をすべての要素に適用し、reduce()関数はその関数を連続的に適用することを保証します。
reduce()とmap()関数を使用する際には、リストアイテムの順序が重要です。同じアイテムを持つリストでも、順序が異なる場合、等価性の比較でtrueが返されません。必要な場合は、まずリストをソートすることができます。
以下の例は、reduce()関数とmap()関数を使用してリストの等価性を比較する方法を示しています。
import functools
l1 = [10, 20, 30, 40, 50]
l2 = [20, 30, 50, 40, 70]
l3 = [10, 20, 30, 40, 50]
if functools.reduce(lambda x, y : x and y, map(lambda p, q: p == q,l1,l2), True):
print ("The lists l1 and l2 are the same")
else:
print ("The lists l1 and l2 are not the same")
if functools.reduce(lambda x, y : x and y, map(lambda p, q: p == q,l1,l3), True):
print ("The lists l1 and l3 are the same")
else:
print ("The lists l1 and l3 are not the same")
結果は: (kekkai wa:)
The lists l1 and l2 are not the same The lists l1 and l3 are the same
前の例のコードは、l1をl2と比較し、そしてl1をl3と比較します。
リストを比較するためにset()関数を使用する
与えられたリストを使用して、set()関数を使ってsetオブジェクトを作成し、==演算子を使用してセットの等しさを比較することができます。
オリジナルのリストの順序は重要ではありません。なぜなら、==演算子は、それぞれのセットが同じアイテムを任意の順序で含んでいる場合にtrueを返すからです。
Note
以下の例は、リストからセットを作成し、セットを等しいかどうか比較する方法を示しています。
l1 = [10, 20, 30, 40, 50]
l2 = [50, 10, 30, 20, 40]
a = set(l1)
b = set(l2)
if a == b:
print("Lists l1 and l2 are equal")
else:
print("Lists l1 and l2 are not equal")
出力は:
Lists l1 and l2 are equal
この前の例のコードは、リストl1とl2から集合aとbを作成し、それから集合を比較して結果を出力します。
リストを比較するために、collections.Counter() クラスを使用する。
collections.Counter()クラスを使用すると、リストを比較することができます。counter()関数は、リスト内のアイテムの頻度をカウントし、そのデータをvalue:frequencyの形式で辞書オブジェクトとして格納します。2つのリストが同じ辞書の出力を持っている場合、それらのリストは同じであると推測することができます。
オリジナルのリストの順序は、リストを比較する際にCounterクラスを使用する場合には重要ではありません。
次の例は、与えられたリストからCounterオブジェクトを作成し、それらを等しく比較する方法を示しています。
import collections
l1 = [10, 20, 30, 40, 50]
l2 = [20, 30, 50, 40, 70]
l3 = [50, 20, 30, 40, 10]
if collections.Counter(l1) == collections.Counter(l2):
print ("The lists l1 and l2 are the same")
else:
print ("The lists l1 and l2 are not the same")
if collections.Counter(l1) == collections.Counter(l3):
print ("The lists l1 and l3 are the same")
else:
print ("The lists l1 and l3 are not the same")
出力は次の通りです。
The lists l1 and l2 are not the same The lists l1 and l3 are the same
前の例のコードでは、リストl1とl2のためのCounterオブジェクトを作成し、それらを比較して結果を出力します。同様のコードがリストl1とl3についても繰り返されます。
リスト内包表記を使用してリストを比較する
Python 3でリスト内包表記を使って2つのリストを比較することができます。リスト内包表記の詳細については、「Python 3でのリスト内包表記の理解」を参照してください。
リスト内包表記を使用してリストを比較する場合、元のリストアイテムの順序は重要ではありません。
以下の例は、リスト内包表記を使用してリストを比較する方法を示しています。
l1 = [10, 20, 30, 40, 50]
l2 = [50, 75, 30, 20, 40]
l3 = [50, 20, 30, 40, 10]
res = [x for x in l1 + l2 if x not in l1 or x not in l2]
print(res)
if not res:
print("Lists l1 and l2 are equal")
else:
print("Lists l1 and l2 are not equal")
res2 = [x for x in l1 + l3 if x not in l1 or x not in l3]
print(res2)
if not res2:
print("Lists l1 and l3 are equal")
else:
print("Lists l1 and l3 are not equal")
前の例のコードでは、ポインタ要素xをリストl1とl2に設定し、その後、ポインタ要素が指し示すアイテムがリストに存在するかどうかをチェックします。もし結果のresが空のリストであれば、リストの中で片方のリストにしか現れないアイテムがないため、リストが等しいと推測できます。
出力は以下の通りです。
[10, 75] Lists l1 and l2 are not equal
結論
この記事では、Pythonでリストを等しく比較するためのいくつかの異なる方法が説明されています。Pythonのチュートリアルをさらに進めて学習を続けましょう。