40

重複が多いPythonリストがあり、重複ではなく各アイテムを反復処理したい場合は、セットを使用するのが最善ですか(のようにset(mylist)、または重複のないリストを作成する別の方法を見つけますか?)リストをループして重複をチェックすることを考えていましたが、set()初期化するとそれが行われると思いました。

それで、もしmylist = [3,1,5,2,4,4,1,4,2,5,1,3]私が本当にループしたいだけなら[1,2,3,4,5](順序は関係ありません)、私はset(mylist)何か他のものを使うべきですか?

最後の例では、リストに最小値と最大値の間のすべての整数が含まれているため、ループスルーrange(min(mylist),max(mylist))またはループする可能性がありますset(mylist)。この場合、通常、setの使用を避けるようにすべきですか?また、を見つけるのはminmax単に作成するよりも遅くなりsetますか?


最後の例の場合、setはより高速です。

from numpy.random import random_integers
ids = random_integers(1e3,size=1e6)

def set_loop(mylist):
    idlist = []
    for id in set(mylist):
        idlist.append(id)
    return idlist

def list_loop(mylist):
    idlist = []
    for id in range(min(mylist),max(mylist)):
        idlist.append(id)
    return idlist

%timeit set_loop(ids)
#1 loops, best of 3: 232 ms per loop

%timeit list_loop(ids)
#1 loops, best of 3: 408 ms per loop
4

5 に答える 5

39

を使用するだけsetです。そのセマンティクスはまさにあなたが望むものです: ユニークなアイテムのコレクションです。

技術的には、リストを 2 回繰り返し処理します。1 回目はセットを作成するため、もう 1 回は実際のループ用です。しかし、他のアプローチと同じかそれ以上の作業を行うことになります。

于 2013-02-27T00:29:28.647 に答える
10

setが必要なので、使用する必要がありますset。賢くしようとすると、max(mylist)!に 1 を追加するのを忘れるなどの微妙なバグが発生します。防御的にコーディングします。遅すぎると判断した場合は、何が速いかを心配してください。

range(min(mylist), max(mylist) + 1)  # <-- don't forget to add 1
于 2013-02-27T01:38:36.933 に答える
8

構造的にはasetが必要な場合がありますが、問題は何がより高速かということです。リストの方が高速です。でリストからセット変換してから、でループする を作成しているため、コード例はsetvsを正確に比較しません。繰り返し処理するセットとリストは、事前に構築してメモリ内に格納し、単純にループして、どのデータ構造が繰り返し処理の速度が速いかを確認する必要があります。list set_looplist list_loop

ids_list = range(1000000)
ids_set = set(ids)
def f(x):
    for i in x:
         pass

%timeit f(ids_set)
#1 loops, best of 3: 214 ms per loop
%timeit f(ids_list)
#1 loops, best of 3: 176 ms per loop
于 2015-11-20T05:04:01.370 に答える
6

簡単にするために:newList = list(set(oldList))

ただし、代わりに速度/順序付け/最適化を取得したい場合は、より良いオプションがあります: http://www.peterbe.com/plog/uniqifiers-benchmark

于 2013-02-27T00:31:23.307 に答える