2017-06-19 13 views
0

私は、順序付けされた一意の値だけを保持するためにpython(2.7)リストをフィルタリングする必要がある多くのタスクに遭遇します。私の通常のアプローチは、コレクションからodereddictを使用することである:Pythonリストを順序付けられた一意の値に変換する

from collections import OrderedDict 

ls = [1,2,3,4,1,23,4,12,3,41] 

ls = OrderedDict(zip(ls,['']*len(ls))).keys() 

print ls 

出力である:

[1、2、3、4、23、12、41]

がありますPythonでそれを行うアートメソッドの他の状態は?

  • 注 - 入力と出力がlist

として与えられるべきで編集 - メソッドの比較はここで見つけることができます: https://www.peterbe.com/plog/uniqifiers-benchmark

最善の解決策が一方です。

def get_unique(seq): 
    seen = set() 
    seen_add = seen.add 
    return [x for x in seq if not (x in seen or seen_add(x))] 
+0

この情報はお役に立ちますか? htt38://wiki.python.org/moin/HowTo/Sorting – Jaxi

+0

いいえ、私は '' sort''オプションを探していません – Dimgold

+0

私は答えを投稿しようとしていましたが、このスレッドはロックされています。 'O(1)'のどちらかの要素から要素にアクセスします。 –

答えて

-1

ls = [1, 2, 3, 4, 1, 23, 4, 12, 3, 41] 

lookup = set() # a temporary lookup set 
ls = [x for x in ls if x not in lookup and lookup.add(x) is None] 
# [1, 2, 3, 4, 23, 12, 41] 

は、これはあなたのアプローチよりもかなりに高速である必要があります。oあなたが好きそれを行うことができ、順番を維持し、は、重複を取り除きます。

3

あなたはこのようsetを使用することができます。

newls = [] 
seen = set() 

for elem in ls: 
    if not elem in seen: 
     newls.append(elem) 
     seen.add(elem) 
+0

申し訳ありませんが、オリジナルよりもさらに複雑になります(ループの場合は2つの追加メモリ構造)。 – Dimgold

+1

セットは必要ありません。 – Netwave

+1

@Dimgold:そうですね、もう少し冗長ですが、 'import'sを必要とせず、' OrderedDict.keys'を使うよりも効率的かもしれません。 –

0

はそうする関数を定義する:

def uniques(l): 
    retl = [] 
    for x in l: 
     if x not in retl: 
      retl.append(x) 
    return retl 
ls = [1,2,3,4,1,23,4,12,3,41] 
uniques(ls) 
[1, 2, 3, 4, 23, 12, 41] 
+0

オリジナルは** O(n)** – Dimgold

+0

@Dimgoldの間に、このアルゴリズムよりも確実に確かに** O(n^2)**実際には** O(n * log(n))**ですが、3つの中間構造を作成することは避けてください。 – Netwave

+0

なぜログ?それはソートされていません。私はどこにボトルネックがあるのか​​把握しようとしています。私はかなりアルゴリズムの観点から - @ eugeneの提案が最も効率的です – Dimgold

0

別の解決策は、次のようにリストの内包表記を使用することになります。

[x for i, x in enumerate(ls) if x not in ls[:i]] 

出力:

[1, 2, 3, 4, 23, 12, 41] 
+0

オリジナルは** O(n)**の間、このアルゴリズムは少なくとも** O(n^2)**(追加を数えていない) – Dimgold

関連する問題