2011-11-01 6 views
9

私はこのようなデータ構造があります。順序を保持しながら、非ハッシュ要素を含むPythonリストから重複要素を削除しますか?

[ 
[('A', '1'), ('B', '2')], 
[('A', '1'), ('B', '2')], 
[('A', '4'), ('C', '5')] 
] 

をそして、私はこの取得したい:

[ 
[('A', '1'), ('B', '2')], 
[('A', '4'), ('C', '5')] 
] 

が示すように、順序を維持しながら、これを行うのに良い方法はありますか?コピー&ペーストのための

コマンド:

sample = [] 
sample.append([('A', '1'), ('B', '2')]) 
sample.append([('A', '1'), ('B', '2')]) 
sample.append([('A', '4'), ('C', '5')]) 
+0

は常に隣接する重複はありますか? – Cameron

+0

@Cameron:必ずしもそうではありません。 – Legend

答えて

7

これはうまくずっと前に有名なPythonistaで答えたやや有名な質問です:http://code.activestate.com/recipes/52560-remove-duplicates-from-a-sequence/

あなたが等しいレコードが隣接していると仮定できる場合があり、 itertools docsでのレシピ:

from operator import itemgetter 
from itertools import groupby, imap 

def unique_justseen(iterable, key=None): 
    "List unique elements, preserving order. Remember only the element just seen." 
    # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B 
    # unique_justseen('ABBCcAD', str.lower) --> A B C A D 
    return imap(next, imap(itemgetter(1), groupby(iterable, key))) 

あなただけ二分メートルを使用してバリアントは、ここでは、注文可能な要素を想定することができる場合モジュール。 n入力がrの一意の値で与えられると、その探索ステップのコストはO(n log r)である。新しい一意の値が見つかった場合は、リストに挿入され、コストはO(r * r)です。

from bisect import bisect_left, insort 

def dedup(seq): 
    'Remove duplicates. Preserve order first seen. Assume orderable, but not hashable elements' 
    result = [] 
    seen = [] 
    for x in seq: 
     i = bisect_left(seen, x) 
     if i == len(seen) or seen[i] != x: 
      seen.insert(i, x) 
      result.append(x) 
    return result 
+0

Tim Petersの唯一の注文保存レシピはブルートフォースです。順序を保持しながらO(n log n)のパフォーマンスを維持するためにソートレシピを変更することができます。 –

+0

注文保存型はAlex Martelliのもので、コメントのTimのコードの下にリストされています。 –

+2

私が知る限り、アレックス・マルテッリの変種はすべて可達性を仮定しています。 –

5

ここではソート/ユニークイディオムの順序保存バリアントです。あなたのアイテムが少なくともソート可能であるなら、これはあなたにO(n log n)のパフォーマンスを与えます。

def unique(a): 
    indices = sorted(range(len(a)), key=a.__getitem__) 
    indices = set(next(it) for k, it in 
        itertools.groupby(indices, key=a.__getitem__)) 
    return [x for i, x in enumerate(a) if i in indices] 

例(単純化のためのハッシュ可能項目と):

>>> a = ['F', 'J', 'B', 'F', 'V', 'A', 'E', 'U', 'B', 'U', 'Z', 'K'] 
>>> unique(a) 
['F', 'J', 'B', 'V', 'A', 'E', 'U', 'Z', 'K'] 
+0

ニース。どのように動作するかは分かります。賢い –

関連する問題