Pythonでリスト・タプルに重複する要素があるかを判定する方法

Pythonでリストとタプルの要素が重複しているかを判定する方法について解説します。

Pythonでリスト・タプルに重複する要素があるかを判定する方法

Pythonで、リスト(配列)とタプルの要素が重複しているかどうかを判定する方法について解説します。

リストやタプルから重複した要素を抽出・削除する方法については、以下の記事を参考にしてください。

Pythonのリスト・タプルに重複した要素があるかを判定する

Pythonでリストやタプルに重複した要素があるかを判定するには、set()コンストラクタを使います。

PythonのSet型は、重複した要素を持たない、順序を持たないなどの特徴を持ったコレクションです。Set型のコンストラクタであるset()にリストなどのイテラブルなオブジェクトを与えることで、重複を持たないSet型オブジェクトを返します。

そのため、リストなどのコレクションの要素数を、Set型にしたものの要素数と比較することで、重複した要素があるかを判定することができます。要素数はPythonの組み込み関数len()を使って確認できます。

# リスト・タプルに重複したようをがあるかを判定する

def has_duplicates(l):
    return len(l) != len(set(l))

# リストの重複判定
l = [1, 2, 3, 4, 5]
print(has_duplicates(l))
# False

l2 = [1, 2, 2, 3, 4, 5]
print(has_duplicates(l2))
# True


# タプルでも同様に判定できる
t = (1, 2, 3, 4, 5)
print(has_duplicates(t))
# False

t2 = (1, 2, 2, 3, 4, 5)
print(has_duplicates(t2))
# True

ネストしたリストに重複した要素があるかを判定する方法

Set型は、要素にイミュータブル(変更不可能)なオブジェクトしかとることができないため、リストのようなミュータブル(変更可能)なオブジェクトを要素としたリスト(ネストしたリスト)に対しては、上記の方法で要素の重複を判定できません。

# setコンストラクタはミュータブルな要素を持つことができない

l = [[1, 2], [3, 4], [5, 6]]
set(l)
# TypeError: unhashable type: 'list'

一方でタプルはイミュータブルなオブジェクトなので、同じ内容でもリストの要素がタプルであれば、最初に紹介した方法で重複を判定することができます。

# タプルを要素としたリストはsetコンストラクタを使用できる

# タプルを要素としたリスト
l = [(1, 2), (3, 4), (5, 6)]
set(l)
# {(1, 2), (3, 4), (5, 6)}

# タプルを要素としたリストの重複判定
print(has_duplicates(l))
# False

l2 = [(1, 2), (1, 2), (5, 6)]
print(has_duplicates(l2))
# True


# タプルを要素としたタプルでも同様の方法を使うことができる
t = ((1, 2), (3, 4), (5, 6))
print(has_duplicates(t))
# False

t2 = ((1, 2), (1, 2), (5, 6))
print(has_duplicates(t2))
# True

まずは、ネストしたリストの要素で、順番も含めて同じリストが含まれているかどうかを判定する方法を解説します。

リスト内包表記を利用してユニークな要素のみにした上で、元のリストの要素数と比較をします。

# ネストしたリストの要素に重複があるかを確認する

def has_duplicates_for_nested(l):
    checked = []
    unique = [x for x in l if x not in checked and not checked.append(x)]
    return len(l) != len(unique)

l1 = [[1, 2], [3, 4], [5, 6]]
l2 = [[1, 2], [3, 4], [1, 2]]

print(has_duplicates_for_nested(l1))
# False
print(has_duplicates_for_nested(l2))
# True

ネストされたリストの中の要素も含めて、リスト全体の要素で重複があるかを判定するには、ネストされたリストを1次元のリストに直してから判定します

# ネストされたリストの要素も含めて重複を判定する

l1 = [[1, 2], [3, 4], [5, 6]]
l2 = [[1, 2], [3, 4], [1, 2]]

l1_flat = [x for l in l1 for x in l]
print(l1_flat)
# [1, 2, 3, 4, 5, 6]
print(has_duplicates(l1_flat))
# False

l2_flat = [x for l in l2 for x in l]
print(l2_flat)
# [1, 2, 3, 4, 1, 2]
print(has_duplicates(l2_flat))
# True