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を使用しないようにする必要がありますか?また、min
とmax
を見つけることは、単に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
_
set
を使用してください。そのセマンティクスはまさにあなたが望むものです:ユニークなアイテムのコレクション。
技術的には、リストを2回繰り返します。1回はセットを作成し、もう1回は実際のループに使用します。しかし、他のアプローチでも同じくらいの作業を行うことになります。
set
は必要なものなので、set
を使用する必要があります。賢くしようとすると、tomax(mylist)
を1つ追加するのを忘れるなどの微妙なバグが発生します。防御的にコーディングします。遅すぎると判断した場合の高速化について心配します。
range(min(mylist), max(mylist) + 1) # <-- don't forget to add 1
簡単にするために:newList = list(set(oldList))
ただし、代わりにspeed/ordering/optimizationを取得する場合は、より優れたオプションがあります。 http://www.peterbe.com/plog/uniqifiers-benchmark
set
が構造的に必要な場合もありますが、問題はより高速なものです。リストは高速です。リストからセットに変換するため、サンプルコードはset
とlist
を正確に比較しませんinset_loop
を作成し、list
を作成します-inlist_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
私はリストが2回ループすると大きく変化し、リストではなくセットをループしているときに2回目に多くの時間がかかります。
generator
とset
のパワーが必要だと思います。
def first_test():
def loop_one_time(my_list):
# create a set to keep the items.
iterated_items = set()
# as we know iterating over list is faster then list.
for value in my_list:
# as we know checking if element exist in set is very fast not
# metter the size of the set.
if value not in iterated_items:
iterated_items.add(value) # add this item to list
yield value
mylist = [3,1,5,2,4,4,1,4,2,5,1,3]
for v in loop_one_time(mylist):pass
def second_test():
mylist = [3,1,5,2,4,4,1,4,2,5,1,3]
s = set(mylist)
for v in s:pass
import timeit
print(timeit.timeit('first_test()', setup='from __main__ import first_test', number=10000))
print(timeit.timeit('second_test()', setup='from __main__ import second_test', number=10000))
出力:
0.024003583388435043
0.010424674188938422
注:この手法の順序は保証されています