BETA

#2 PythonでListの中のListをuniqueにする方法

投稿日:2018-11-16
最終更新:2018-11-16
※この記事は外部サイト(https://medium.com/@yamasaKit/2-python%E3%...)からのクロス投稿です

TL; DR

PythonではListをuniqueにするのは手間がかかります。 Tupleに対してはsetが使えるので一度Tupleにしてsetを使ってuniqueにし、またListに戻しましょう。

*今回紹介する方法はList内の要素の順番は担保されません。

duplicated_data = [
    ['a', 'b', 'c'],
    ['b', 'c'],
    ['a', 'b', 'c'],
    ['d', 'e'],
    ['d', 'e'],
    ['b', 'c'],
    ['e', 'd'],
]
duplicated_data = [tuple(d) for d in duplicated_data]
unique_data = set(duplicated_data)
unique_data = [list(d) for d in unique_data]
print(unique_data)
[['b', 'c'], ['a', 'b', 'c'], ['d', 'e'], ['e', 'd']]

背景

データを整理しuniqueにしたい(重複がないようにしたい)ことは解析中などによくあります。数字や文字の集合の場合はsetを使うと良いです。

a = [1, 3, 2, 2, 5, 3, 1, 100]
print(set(a))
{1, 2, 3, 100, 5}

上の例のようにsetを使うだけでuniqueな集合にしてくれます。

b = ['Alice', 'Bob', 'Carol', 'Alice', 'Alice']
print(set(b))
{'Alice', 'Carol', 'Bob'}

文字列もuniqueな集合にしてくれます。

しかし、表題のようにListの要素を見て、同じ要素であった場合は削除してuniqueな集合にしたいと思って試しにやってみても

duplicated_data = [
    ['a', 'b', 'c'],
    ['b', 'c'],
    ['a', 'b', 'c'],
    ['d', 'e'],
    ['d', 'e'],
    ['b', 'c'],
    ['e', 'd'],
]
set(duplicated_data)
TypeError: unhashable type: 'list'

エラーが出てuniqueにすることができません。Listはできないよって書いてますね。

解決策

Tupleに対してはsetが使えるので一度Tupleにしてsetを使ってuniqueにし、またListに戻しましょう。最初にお見せした例をもう一度書いておきます。

duplicated_data = [
    ['a', 'b', 'c'],
    ['b', 'c'],
    ['a', 'b', 'c'],
    ['d', 'e'],
    ['d', 'e'],
    ['b', 'c'],
    ['e', 'd'],
]
duplicated_data = [tuple(d) for d in duplicated_data]
unique_data = set(duplicated_data)
unique_data = [list(d) for d in unique_data]
print(unique_data)
[['b', 'c'], ['a', 'b', 'c'], ['d', 'e'], ['e', 'd']]

もちろんTupleのままで特に問題ないならListに戻さなくてもOKです。

上の例だと [’d’, ’e’] と [’e’, ’d’] は別のものと考えられてどちらも残っていますね。もしこれらも取り除きたいならあらかじめsortしておきましょう。

duplicated_data = [
    ['a', 'b', 'c'],
    ['b', 'c'],
    ['a', 'b', 'c'],
    ['d', 'e'],
    ['d', 'e'],
    ['b', 'c'],
    ['e', 'd'],
]
duplicated_data = [tuple(sorted(d)) for d in duplicated_data]
unique_data = set(duplicated_data)
unique_data = [list(d) for d in unique_data]
print(unique_data)
[['b', 'c'], ['a', 'b', 'c'], ['d', 'e']]

[’d’, ’e’]と[’e’, ’d’] がまとめられましたね。

最後に

今回の方法の注意点はList内の要素の順番は担保されないということです。つまり最初の要素の順番を残しつつuniqueにしたいという場合にはそのまま使えずもう一工夫必要です。sortした場合も元の順番の情報がなくなってしまいます。

順番が変わってもいいよって場合は内包表記で書きやすいことからも手軽にできる作業でオススメです。ぜひ試してみてください。

Listでは無理だけどTupleならできることに気づいた瞬間に私の中で大幅にTupleの株が上がりました。

Python (version 3.6)

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@yamasaKit'の技術ブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる
技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
or 外部アカウントではじめる
10秒で技術ブログが作れます!