Pythonでリスト・タプルから重複した要素を抽出・削除する方法

Pythonのリスト(配列)から重複要素を抽出・削除する方法について解説します。

Pythonでリスト・タプルから重複した要素を抽出・削除する方法

Pythonのリスト(配列)・タプルから、重複した要素を抽出・削除して、一意でユニークな要素のみのリストを作成する方法について解説します。やりたいことに従って、大きく以下の二つの実装方法を紹介します。

  • 重複した要素を抽出する(元のリストの中に二つ以上存在する要素だけを取り出して新しいリストにする)
  • 重複した要素を削除する(元のリストの中から重複を削除し、すべての要素がユニークなリストにする)

単純にリストやタプルが重複した要素を持っているかを判定したい場合には、以下の記事を参考にしてください。

リスト・タプルから重複した要素を抽出する

重複している要素を抽出して新しいリストやタプルを作るには、collectionsモジュールのCounterクラスを使います。このクラスは、引数として渡したリスト・タプルの要素をキーとして、その個数を値にしたオブジェクトを辞書のような形で返します。

Counterクラスは辞書のサブクラスなので、items()メソッドでキーと値を取り出し、個数が2つ以上(重複しているもの)のみを取り出して新しいリストやタプルを作ることができます。

# リスト・タプルで重複する要素を抽出して新しいリスト・タプルを作成

import collections

items_list = [3, 2, 1, 1, 2]

# Counter型に変換すると、要素の個数を表す辞書のような形式になる。
items_list_collection = collections.Counter(items_list)
print(items_list_collection)
# Counter({2: 2, 1: 2, 3: 1})

# リスト内包表記で、個数が2個以上のキーを要素として取り込む
new_items_list = [k for k, v in items_list_collection.items() if v > 1]
print(new_items_list)
# [2, 1]


# タプルでも同様の操作が可能、リスト内包表記の形で書くとジェネレータ式になるので注意
items_tuple = (3, 2, 1, 1, 2)
items_tuple_collection = collections.Counter(items_tuple)
new_items_tuple = tuple(k for k, v in items_tuple_collection.items() if v > 1)
print(new_items_tuple)
# (2, 1)

この方法は、元のリストやタプルの要素の順序も保持します

リスト内包表記については以下の記事を参考にしてください。

リスト・タプルから重複した要素を削除する

リストやタプルには要素の順序の概念があります。重複した要素を削除する際に、元々のリスト・タプルの順序を保持したい場合と順序は無視できる場合によって、実装の方法が異なります。

元のリスト・タプルの順序を保持する場合

元々のリスト・タプルの順序を保持したい場合には、辞書型dictのクラスメソッドであるfromkeys()を使います。このメソッドは、引数に指定したリストやタプルの要素をキーとした辞書オブジェクトを生成します。辞書オブジェクトは重複したキーを持たず、元々のリスト・タプルの順番を保持してくれます。

辞書オブジェクトをlist()関数やtuple()関数で変換すると、辞書のキーを要素としてリストやタプルを作成します。そのため、以下のような実装で要素の順番を保ったまま、重複した要素を削除することができます。

# リスト・タプルの順序を保持して重複した要素を削除する

items_list = [3, 2, 1, 1, 2]
items_tuple = (3, 2, 1, 1, 2)

print(list(dict.fromkeys(items_list)))
# [3, 2, 1]

print(tuple(dict.fromkeys(items_tuple)))
# (3, 2, 1)

元のリスト・タプルの順序を保持しない場合

元々のリスト・タプルの順序を保持しなくて良い場合には、set()を使います。集合型setは、重複した要素を持たないので、リスト・タプルを引数として渡すと、ユニークな値のみが要素として抽出されたset型のオブジェクトを返します。これをlist()またはtuple()でリスト・タプルに変換すれば、重複した要素を削除することができます。

# リスト・タプルの順序を保持せず、重複した要素を削除する

items_list = [3, 2, 1, 1, 2]
items_tuple = (3, 2, 1, 1, 2)

print(list(set(items_list)))
# [1, 2, 3]

print(tuple(set(items_tuple)))
# (1, 2, 3)