4

任意のアイテムのリスト(私の例ではリストのリスト)からすべての複数の出現アイテムを削除する最も速い方法は何ですか?結果として、リストに1回だけ出現するアイテムのみが表示され、すべての重複が削除されます。

入力:[[1、2]、[1、3]、[1、4]、[1、2]、[1、4]、[1、2]]

出力:[[1、3]、]

この解決策は遅かった:

output = [item for item in input if input.count(item)==1]

このソリューションはより高速でした:

duplicates = []
output = []
for item in input:
    if not item in duplicates:
        if item in output:
            output.remove(item)
            duplicates.append(item)
        else:
           output.append(item)

おそらく最初にリストをソートすることによって、より良い解決策はありますか?どんなアイデアでも大歓迎です。

4

2 に答える 2

8

注文の保存を気にしない場合:

from collections import Counter

def only_uniques(seq):
    return [k for k,n in Counter(seq).iteritems() if n == 1]

注文の保存に関心がある場合:

from collections import Counter

def only_uniques_ordered(seq):
    counts = Counter(seq)
    return [k for k in seq if counts[k] == 1]

両方のアルゴリズムはO(n)時間内に実行されます。


編集:リストのリストがあることを忘れました。シーケンスをハッシュできるようにするには、シーケンスが不変である必要があるため、次のようなことができます。

list_of_tuples = [tuple(k) for k in list_of_lists]

次に、list_of_tuples代わりに上記の関数の1つを実行します。タプルのリストがそこから戻されることに注意してください。ただし、この後にシーケンスを再度変更する場合を除いて、タプルは目的に応じて機能するはずです。

元に戻す必要がある場合でも、ほとんど同じです。

list_of_lists = [list(k) for k in list_of_tuples]
于 2013-03-17T23:18:13.613 に答える
2
a = [[1, 2], [1, 3], [1, 4], [1, 2], [1, 4], [1, 2]]
print list(set(tuple(i) for i in a))

1つのライナーの上で仕事をします。

user $ time python foo.py
[(1、2)、(1、3)、(1、4)]

実際の0m0.037s
ユーザー
0m0.024ssys0m0.010s

質問者からの質問に応じて、固有のアイテムのみを印刷します。ソリューションは、コレクションモジュールを使用していないことを除いて、Amberのソリューションの変形です。

a = [[1, 2], [3, 4], [1, 3], [1, 4], [1, 2], [1, 4], [1, 2]]
d = {tuple(i): a.count(i) for i in a}
print [k for k, v in d.iteritems() if v == 1]

出力:

[(1, 3), (3, 4)]
于 2013-03-17T23:36:29.480 に答える