リスト内の重複データを取り除きたい場合、集合型 set() を使うのが一般的ですが、set() は要素の並び順を保持しません。 データの出現順序を維持したまま重複だけを取り除きたい場合は、辞書型(dict)の特性を利用する dict.fromkeys() メソッドが最適です。
ここでは、検索履歴データを例に、順序を守ってユニークなリストを作成する方法を解説します。
目次
解決したい課題
Webブラウザやアプリの「最近チェックした項目」のように、新しい順(あるいは古い順)という並び順には意味があるため、単純な重複削除で順序がバラバラになっては困るケースがあります。
実装例:検索キーワード履歴の重複整理
ユーザーが検索したキーワードの履歴リストから、重複を取り除いて一意なリストを作成します。この際、検索された順番はそのまま維持します。
ソースコード
# ユーザーによる検索キーワードの履歴(時系列順)
# "python" や "tutorial" が重複して登場しています
search_history = [
"python",
"tutorial",
"django",
"python", # 重複
"machine-learning",
"tutorial", # 重複
"web-design"
]
print(f"元のリスト: {search_history}")
# dict.fromkeys() を使用して重複を削除しつつ順序を保持
# 1. search_history の要素をキーとする新しい辞書を作成(辞書のキーは重複できないためユニークになる)
# 2. list() で辞書のキーだけを取り出してリストに戻す
unique_history = list(dict.fromkeys(search_history))
print(f"処理後のリスト: {unique_history}")
実行結果
元のリスト: ['python', 'tutorial', 'django', 'python', 'machine-learning', 'tutorial', 'web-design']
処理後のリスト: ['python', 'tutorial', 'django', 'machine-learning', 'web-design']
解説
なぜ dict.fromkeys() なのか
- 重複の排除: 辞書のキー(Key)は一意である必要があるため、リストを辞書のキーに変換する過程で自動的に重複が取り除かれます。
- 順序の保持: Python 3.7以降の標準仕様では、辞書は挿入された順序を保持します。これにより、リストの先頭から順番にキーとして登録され、結果として元のリストの出現順序が保たれます。
set() との違い
参考までに、set() を使った場合の挙動と比較します。
# setを使った場合(順序は保証されない)
print(list(set(search_history)))
# 出力例: ['web-design', 'django', 'python', 'machine-learning', 'tutorial']
# -> 順番がバラバラになる可能性があります
順序が重要でない場合は高速な set() を、順序が重要な場合は dict.fromkeys() を使い分けると良いでしょう。
