Pythonでリスト内の重複する要素の列を削除する方法
Pythonでネストされたリスト(リストのリスト)を扱っていると、複数のサブリストにまたがって同じ要素が重複して現れる「列」を削除したい場面があります。本記事では、空のセット(set)を活用して重複する列を検出し、削除する方法をわかりやすく解説します。
基本的なアプローチはシンプルです。まず空のセットを用意し、各サブリストを先頭から順番に走査します。まだセットに存在しない要素であればセットに追加し、すでに存在する要素であれば、その位置(インデックス)を削除候補として記録します。最後に、記録したインデックスを除外した新しいリストを生成すれば、重複する列を取り除いた結果が得られます。
サンプルコード
以下に具体的な実装例を示します。
from itertools import chain
def remove_dupes(my_sub):
my_string = set()
for i, elem in enumerate(my_sub):
if elem not in my_string:
my_string.add(elem)
else:
yield i
my_list = [[5, 1, 6, 7, 9], [6, 3, 1, 9, 1], [4, 2, 9, 8, 9], [5, 1, 6, 7, 3]]
print('元のリスト :')
print(my_list)
K = 3
temp_idxs = set(chain.from_iterable(remove_dupes(sub) for sub in my_list))
my_result = [[elem for i, elem in enumerate(sub) if i not in temp_idxs] for sub in my_list]
print('重複する列を削除した結果 :')
print(my_result)
実行結果
元のリスト : [[5, 1, 6, 7, 9], [6, 3, 1, 9, 1], [4, 2, 9, 8, 9], [5, 1, 6, 7, 3]] 重複する列を削除した結果 : [[5, 1, 6, 7], [6, 3, 1, 9], [4, 2, 9, 8], [5, 1, 6, 7]]
この例では、2番目と3番目のサブリスト内で同じ値が2回現れる位置(インデックス4)が検出され、すべてのサブリストから該当する列が削除されています。そのため、どのサブリストも末尾の要素が取り除かれた形になっています。
コードの解説
- モジュールのインポート:複数のイテラブルを一つに連結するために、
itertoolsモジュールのchain関数をインポートします。 - ジェネレータ関数の定義:
remove_dupesという関数を定義し、サブリストを引数として受け取ります。 - 空のセットを作成:確認済みの要素を記録するための空のセット
my_stringを用意します。 - 要素の走査:
enumerateを使ってインデックスと要素を同時に取得しながら、リストを先頭から順に調べます。 - 重複チェック:要素がセットに存在しない場合はセットに追加し、すでに存在する場合はそのインデックスを
yieldで返します。 - データの準備:関数の外側でリストのリストを定義し、コンソールに表示します。
- 変数Kの定義:値
Kを定義しています(このサンプルコードでは直接は使用されていません)。 - 重複インデックスの収集:各サブリストに対して
remove_dupesを呼び出し、chain.from_iterableで結果を連結してからセットに変換し、temp_idxsに代入します。 - 結果の生成:リスト内包表記を用いて、
temp_idxsに含まれないインデックスの要素だけを取り出し、新しいリストを作成します。 - 結果の出力:最終的な結果をコンソールに表示します。
補足:この手法のポイント
セットによる要素の存在確認は平均的にO(1)で行えるため、リストのin演算子で毎回線形探索するよりも高速に動作します。また、ジェネレータ関数を使って重複インデックスを遅延評価で返すことで、メモリ効率も良好に保たれます。データサイズが大きい場合でも安心して利用できるアプローチです。
-
Pythonで配列内のゼロを複製するアルゴリズムを解説
問題の概要固定長の整数型配列が与えられたとき、配列内に出現するゼロ(0)をそれぞれ2つに複製し、それに応じて残りの要素を右側へずらすという問題を考えてみましょう。ただし、元の配列の長さを超える部分には要素を書き込まない点に注意が必要です。つまり、右にずらされたことで範囲外となった要素は単純に切り捨てられます。例えば、配列が [1,0,2,3,0,4,5,0] の場合、処理後は [1,0,0,2,3,0,0,4] となります。解き方のアプローチこの問題は、以下の手順で解くことができます。元の配列 arr を別の配列 arr2 にコピーし、インデックス i と j をそれぞれ 0 で初期化します。
-
【Python】pop()メソッドでセットから要素を削除する方法
「集合(セット)」という言葉は、数学の分野でおなじみの概念です。Pythonにおけるセット(set)は、数学の集合に相当するデータ構造で、さまざまな要素を格納することができます。セット内の要素には順序が定義されておらず、要素の追加や削除、セット全体の反復処理のほか、和集合・積集合・差集合といった標準的な集合演算も行えます。 本記事では、セットから要素を削除する方法を解説します。ここでは pop() メソッドを使用します。pop() はPythonの組み込みメソッドで、セットから要素を1つずつ取り出して削除するために使われます。なお、セットは順序を持たないデータ構造のため、どの要素が削除されるか