HOWTO · Python

Python でリストからユニークな値を取得する方法

Python でリストからユニークな値を取得する方法を紹介しています。

このページの内容

Python 3.7 以降でリストから一意な値を取得するには、要素がハッシュ可能で、最初に現れた順序を保ちたい場合は list(dict.fromkeys(values)) を使います。要素がハッシュ不可能なら、結果用のリストを使ったループを選びます。順序を問わない場合に限り、set(values) に変換します。

dict.fromkeys() で順序を保って一意な値を取得する

dict.fromkeys() は、入力のイテラブルからキーを作成した辞書を返します。辞書のキーは重複せず、Python 3.7 以降では辞書が挿入順を保つことが保証されています。そのため、キーをリストに戻すと、各値の最初の位置を保ちながら重複を取り除けます。この方法では、通常の辞書キーと同様に、すべての要素がハッシュ可能である必要があります。

次の例を実行します。

このセクションのコードと表示されるラベルや出力は英語のままです。

values = ["pear", "apple", "pear", "plum", "apple"]
unique_values = list(dict.fromkeys(values))
print(unique_values)

出力:

['pear', 'apple', 'plum']

ループで順序を保って一意な値を取得する

ネストしたリストのように値がハッシュ不可能な場合、辞書やセットではその値をキーや要素として使えません。代わりに、明示的なループで、すでに集めた値と各値を比較できます。最初に現れた値を残し、等価性の比較に意味がある値のリストで使えます。

このセクションのコードと表示されるラベルや出力は英語のままです。

values = [[1, 2], [3, 4], [1, 2]]
unique_values = []
for value in values:
    if value not in unique_values:
        unique_values.append(value)
print(unique_values)

value not in unique_values の判定では、結果のリストを毎回検索します。一意な項目が増えるほど比較が繰り返され、この方法はハッシュを使う方法より遅くなることがあります。そのため、速度よりもハッシュ不可能な要素への対応が重要な場合に使います。

順序が重要でない場合は set() で一意な値を取得する

要素がハッシュ可能なら、set(values) で簡潔に重複を取り除けます。セットは入力リストの順序を保たないため、リストに戻したときの特定の並び順を前提にしないでください。セットの要素もハッシュ可能である必要があります。順序が関係しない場合、たとえばメンバーシップを確認したり、含まれる値を比較したりする場合に使います。

このセクションのコードと表示されるラベルや出力は英語のままです。

values = ["pear", "apple", "pear", "plum", "apple"]
unique_values = set(values)
print(unique_values)

表示されるセットの順序は変わることがあります。結果には重複しない値が含まれますが、特定の表示順は保証されません。

リストに合った方法を選ぶ

ハッシュ可能な値について、最初に現れた順序を保った簡潔なリストを作るには dict.fromkeys() を使います。リストなど、ハッシュ不可能な値が含まれる可能性があり、最初に現れた順序も保ちたい場合は、明示的なループを選びます。値がハッシュ可能で、順序に意味がない場合は set() を使います。

ハッシュ可能な入力では、辞書やセットのメンバーシップ判定は平均的に効率よく動作します。一方、ループでは増え続ける結果リストを繰り返し検索します。これらの方法では、Python の等価性とハッシュの動作に基づいて重複を判定します。たとえば 1 と True は等しい値として比較されるため、1つの項目にまとめられます。アプリケーションで別の一意性の基準が必要な場合は、各項目を先に正規化するかキーを導出し、そのキーを使って重複を取り除きます。