Pythonでリストを比較
Pythonで2つのリストを比較・判定する方法について説明する。タプルについても最後に述べる。
リストの大小関係(順序比較)
2つのリストの大小関係・順序を<
, <=
, >
, >=
で比較した結果は以下のように決定される。
順序比較をサポートしているコレクションの順序は、最初の等価でない要素の順序と同じになります (例えば、
[1,2,x] <= [1,2,y]
はx <= y
と同じ値になります)。 対応する要素が存在しない場合、短い方のコレクションの方が先の順序となります (例えば、[1,2] < [1,2,3]
は真です)。 6. 式 (expression) - 値の比較 — Python 3.11.3 ドキュメント
先頭の要素から順に比較され、最初の等価でない要素の比較結果がリスト自体の比較結果になる。
print([1, 2, 3] < [1, 2, 100])
# True
print([1, 2, 3] < [1, 2, 0])
# False
対応する要素が無い場合、要素数が少ない方が先の順序(小さい)とみなされる。
print([1, 2] < [1, 2, 3])
# True
等価でない要素がある場合は要素数は関係なく、あくまでも先頭から順に比較される。
print([100] < [1, 2, 3])
# False
文字列など他の型を要素とするリストでも同様。
print(['a', 'b', 'c'] < ['a', 'b', 'x'])
# True
対応する要素が比較できない型の場合はエラーとなる。
# print([100] < ['a'])
# TypeError: '<' not supported between instances of 'int' and 'str'
リストに対する==(等価比較)
リストに対する==
での比較は、対応する要素を順番に比較してすべて等価であったときにTrue
を返す。そうでない場合はFalse
。
print([1, 2, 3] == [1, 2, 3])
# True
print([1, 2, 3] == [3, 2, 1])
# False
print([1, 2, 3] == [1, 2])
# False
各要素は==
で比較される。型が異なっていても値が等価であればTrue
。型も含めて完全に一致するか判定する方法は後述。
- 関連記事: Pythonの==演算子とis演算子の違い
print([1, 2, 3] == [True, 2.0, 3 + 0j])
# True
!=
は==
の否定。
print([1, 2, 3] != [1, 2, 3])
# False
print([1, 2, 3] != [3, 2, 1])
# True
print([1, 2, 3] != [1, 2])
# True
print([1, 2, 3] != [True, 2.0, 3 + 0j])
# False
なお、is
はオブジェクトの同一性を判定する。2つのリストが同じオブジェクトを指していればTrue
。そうでなければFalse
となる。
l1 = [1, 2, 3]
l2 = [1, 2, 3]
print(l1 is l2)
# False
l1_assign = l1
print(l1_assign)
# [1, 2, 3]
print(l1 is l1_assign)
# True
リストの完全一致を判定
2つのリストが完全一致しているかを判定するには、例えば以下のような関数を定義する。ここでは、2つのリストの要素数が等しく、先頭から順に対応する要素の値も型も一致していることを完全一致と呼んでいる。
- 関連記事: Pythonの組み込み関数all(), any()の使い方
- 関連記事: Pythonリスト内包表記の使い方
def lists_match(l1, l2):
if len(l1) != len(l2):
return False
return all(x == y and type(x) == type(y) for x, y in zip(l1, l2))
print(lists_match([1, 2, 3], [1, 2, 3]))
# True
print(lists_match([1, 2, 3], [1, 2]))
# False
print(lists_match([1, 2, 3], [True, 2.0, 3 + 0j]))
# False
集合として処理(部分一致、部分・上位集合など)
リストを集合(set
)に変換すると、集合演算が可能。
部分一致
2つのリストが部分的に一致しているか、すなわち、共通する要素が少なくとも1つあるかを判定するには、set
のisdisjoint()
メソッドを使う。引数にはset
だけでなくリストなどの他のイテラブルオブジェクトも指定できる。
isdisjoint()
は共通の要素を持たないときにTrue
を返す。したがって、その否定not
が部分一致するかの判定に等しい。
l1 = [1, 2, 3]
l2 = [3, 4, 5]
l3 = [5, 6, 7]
print(not set(l1).isdisjoint(l2))
# True
print(not set(l1).isdisjoint(l3))
# False
判定だけでなく、複数のリストに共通する要素・共通しない要素を抽出したい場合は以下の記事を参照。
部分集合・上位集合(すべて含まれるか)
集合Aのすべての要素が集合Bに含まれているとき、AはBの部分集合、BはAの上位集合という。部分集合か、上位集合かを判定するには、set
のissubset()
, issuperset()
メソッドを使う。
一方のリストの要素が他方のリストにすべて含まれるか、という判定が可能。
l1 = [1, 2]
l2 = [1, 2, 3]
print(set(l1).issubset(l2))
# True
print(set(l2).issuperset(l2))
# True
その他の集合演算
集合set
を利用すると、一方のリストから他方のリストに含まれる要素を取り除いて差分を抽出する、といった処理などもできる。
l1 = [1, 2, 3, 4, 5]
l2 = [2, 3, 4]
print(list(set(l1) - set(l2)))
# [1, 5]
集合set
についての詳細は以下の記事を参照。
タプルの比較
ここまでリストの比較について説明したが、タプルの比較についても同様。
print((1, 2, 3) < (1, 2, 100))
# True
print((1, 2, 3) == (1, 2, 3))
# True
print(set((1, 2)).issubset((1, 2, 3)))
# True
リストとタプルを<
, <=
, >
, >=
で比較するとエラーになる。list()
またはtuple()
で型を揃える必要がある。
l = [1, 2, 3]
t = (1, 2, 3)
# print(l <= t)
# TypeError: '<=' not supported between instances of 'list' and 'tuple'
print(l <= list(t))
# True
リストとタプルを==
で比較するとFalse
を返す。list()
またはtuple()
で型を揃えれば、対応する要素ごとの比較が可能。
print(l == t)
# False
print(l == list(t))
# True