note.nkmk.me

Pythonでリスト(配列)に重複した要素があるか判定

Date: 2018-03-25 / tags: Python, リスト

Pythonで、リスト(配列)に重複した要素があるか(要素が一意・ユニークであるか)を判定する。

  • 要素にリストを持たないリストの場合
  • 要素にリストを持つリスト(二次元配列、リストのリストなど)の場合

について、それぞれ説明する。

リストから重複した要素を削除したり抽出したりする方法は以下の記事を参照。

なお、リストは異なる型のデータを格納可能で、厳密には配列とは異なる。メモリサイズやメモリアドレスを必要とするような処理や大規模なデータの数値計算処理などで配列を扱いたい場合はarray(標準ライブラリ)やNumPyを使う。

スポンサーリンク

リストに重複した要素があるか判定(要素にリストがない場合)

要素にリストなどの更新可能なオブジェクトがない場合は、集合set型のコンストラクタset()を使う。

set型は重複した要素をもたないデータ型で、コンストラクタset()にリストを渡すと、重複する値は無視されて一意な値のみが要素となるset型のオブジェクトを返す。

このset型のオブジェクトと元のリストの要素数を組み込み関数len()で取得し比較する。要素数が等しい場合、元のリストに重複した要素はないといえる。

def is_unique(seq):
    return len(seq) == len(set(seq))

l = [0, 'two', 1, 'two', 0]

print(is_unique(l))
# False

l = [0, 'one', 2]

print(is_unique(l))
# True

例はリストだが、タプルでも同じ関数が使える。

リストなどのミュータブル(更新可能)なオブジェクトはset型の要素にできないため、要素にリストを持つリスト(二次元配列、リストのリストなど)の場合はエラーTypeErrorになる。対応策は次に示す。

# l_2d = [[0, 1], [1, 1], [0, 1], [1, 0]]
# print(is_unique(l_2d))
# TypeError: unhashable type: 'list'

リストに重複した要素があるか判定(要素にリストがある場合)

要素にリストを持つリスト(二次元配列、リストのリストなど)の場合、以下のような関数で重複した要素があるかを判定できる。

def is_unique2(seq):
    seen = []
    unique_list = [x for x in seq if x not in seen and not seen.append(x)]
    return len(seq) == len(unique_list)

l_2d = [[0, 1], [1, 1], [0, 1], [1, 0]]

print(is_unique2(l_2d))
# False

l_2d = [[0, 1], [1, 1], [1, 0]]

print(is_unique2(l_2d))
# True

set()ではなくリスト内包表記で一意な値のみが要素となるリストを生成し、要素数を比較している。詳細は以下の記事を参照。

この関数は要素にリストを持たないリストに対しても有効。

l = [0, 'two', 1, 'two', 0]

print(is_unique2(l))
# False

l = [0, 'one', 2]

print(is_unique2(l))
# True

l = [[0, 1, 2], 'string', 100, [0, 1, 2]]

print(is_unique2(l))
# False

l = [[0, 1, 2], 'string', 100]

print(is_unique2(l))
# True
スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事