Pythonでは、どのデータ構造がより効率的/高速ですか?順序が私にとって重要ではなく、とにかく重複をチェックすると仮定すると、PythonセットはPythonリストよりも遅くなりますか?
Pythonでは、どのデータ構造がより効率的/高速ですか?順序が私にとって重要ではなく、とにかく重複をチェックすると仮定すると、PythonセットはPythonリストよりも遅くなりますか?
回答:
それはあなたがそれで何をしようとしているのかに依存します。
セット内にオブジェクトが存在するかどうかを判断する場合、セットは大幅に高速化されます。 x in s
)、コンテンツの反復処理はリストよりも低速です。
timeitモジュールを使用して、状況に応じてどちらが速いかを確認できます。
値を繰り返し処理したいだけの場合、リストはセットよりもわずかに高速です。
ただし、アイテムがリストに含まれているかどうかを確認する場合、セットはリストよりもはるかに高速です。ただし、一意のアイテムのみを含めることができます。
タプルは、不変性を除いて、リストとほぼ同じように機能することがわかりました。
反復
>>> def iter_test(iterable):
... for i in iterable:
... pass
...
>>> from timeit import timeit
>>> timeit(
... "iter_test(iterable)",
... setup="from __main__ import iter_test; iterable = set(range(10000))",
... number=100000)
12.666952133178711
>>> timeit(
... "iter_test(iterable)",
... setup="from __main__ import iter_test; iterable = list(range(10000))",
... number=100000)
9.917098999023438
>>> timeit(
... "iter_test(iterable)",
... setup="from __main__ import iter_test; iterable = tuple(range(10000))",
... number=100000)
9.865639209747314
オブジェクトが存在するかどうかを確認する
>>> def in_test(iterable):
... for i in range(1000):
... if i in iterable:
... pass
...
>>> from timeit import timeit
>>> timeit(
... "in_test(iterable)",
... setup="from __main__ import in_test; iterable = set(range(1000))",
... number=10000)
0.5591847896575928
>>> timeit(
... "in_test(iterable)",
... setup="from __main__ import in_test; iterable = list(range(1000))",
... number=10000)
50.18339991569519
>>> timeit(
... "in_test(iterable)",
... setup="from __main__ import in_test; iterable = tuple(range(1000))",
... number=10000)
51.597304821014404
リストのパフォーマンス:
>>> import timeit
>>> timeit.timeit(stmt='10**6 in a', setup='a = range(10**6)', number=100000)
0.008128150348026608
セットパフォーマンス:
>>> timeit.timeit(stmt='10**6 in a', setup='a = set(range(10**6))', number=100000)
0.005674857488571661
タプルはリストに似ていますが変更できないため、検討することをお勧めします。メモリの消費量がわずかに少なく、アクセスが高速です。それらは柔軟ではありませんが、リストよりも効率的です。それらの通常の使用は、辞書キーとして機能することです。
セットもシーケンス構造ですが、リストやタプルとは2つの違いがあります。セットには順序がありますが、その順序は任意であり、プログラマーの制御下にはありません。2つ目の違いは、セットの要素は一意でなければならないことです。
>>> x = set([1, 1, 2, 2, 3, 3])
>>> x
{1, 2, 3}
set
型リンク(docs.python.org/2/library/stdtypes.html#set)に更新する必要がありsets
ます。次に、「セットはシーケンス構造でもあります」と組み込みタイプのリンクから次のように読みます。シーケンスのような動作。」
range
はありませんlist
。range
カスタム__contains__
マジックメソッドを持つ特別なクラスです。
xrange
)
Set
ほぼ瞬時の「包含」チェックによる勝利:https : //en.wikipedia.org/wiki/Hash_table
リストの実装:通常は配列で、金属に近い低レベルで、要素インデックスによる反復とランダムアクセスに適しています。
セットの実装:https : //en.wikipedia.org/wiki/Hash_table、それはリストを反復しませんが、ハッシュを計算することによって要素を見つけます、キーからのをます、それでそれはキー要素とハッシュの性質に依存します関数。dictに使用されるものと同様です。私は疑いlist
あなたが非常に少数の要素(<5)を持っている場合は、より大きな要素がより良い数える速くなる可能性set
のチェックが含まれているために実行します。要素の追加と削除も高速です。また、セットの作成にはコストがかかることにも常に注意してください。
注:list
が既にソートされている場合、の検索はlist
かなり高速になる可能性がありますが、通常の場合、a set
は包含チェックの方が高速かつ単純です。
データ構造(DS)は、基本的に意味するデータの操作を実行するために使用されるため、重要です。入力を受け取り、処理し、出力を返します。です。。
一部の特定のケースでは、一部のデータ構造が他のデータ構造よりも有用です。したがって、どちらの(DS)がより効率的/高速であるかを尋ねるのはかなり不公平です。ナイフとフォークの間でより効率的なツールを尋ねるようなものです。つまり、すべては状況に依存します。
リストは変更可能なシーケンスであり、通常、同種のアイテムのコレクションを格納するために使用されます。
セットオブジェクトは、個別のハッシュ可能なオブジェクトの順序付けられていないコレクションです。これは、メンバーシップをテストし、シーケンスから重複を削除し、交差、和集合、差、対称差などの数学演算を計算するために一般的に使用されます。
いくつかの回答から、値を繰り返し処理する場合、リストはセットよりもかなり高速であることは明らかです。一方、アイテムがリストに含まれているかどうかを確認する場合、セットはリストよりも高速です。したがって、あなたが言える唯一のことは、リストは特定の操作ではセットよりも優れており、その逆も同様です。
値が少数のリテラルの1つであるかどうかをCPythonでチェックするときの結果に興味がありました。set
Python 3 vs tuple
で勝利しlist
、or
:
from timeit import timeit
def in_test1():
for i in range(1000):
if i in (314, 628):
pass
def in_test2():
for i in range(1000):
if i in [314, 628]:
pass
def in_test3():
for i in range(1000):
if i in {314, 628}:
pass
def in_test4():
for i in range(1000):
if i == 314 or i == 628:
pass
print("tuple")
print(timeit("in_test1()", setup="from __main__ import in_test1", number=100000))
print("list")
print(timeit("in_test2()", setup="from __main__ import in_test2", number=100000))
print("set")
print(timeit("in_test3()", setup="from __main__ import in_test3", number=100000))
print("or")
print(timeit("in_test4()", setup="from __main__ import in_test4", number=100000))
出力:
tuple
4.735646052286029
list
4.7308746771886945
set
3.5755991376936436
or
4.687681658193469
3から5のリテラルの場合、set
それでも大きな差で勝ちor
、最も遅くなります。
Python 2では、set
常に最も遅いです。or
2~3リテラルの最速であり、tuple
そしてlist
より速く4つの以上のリテラルとしています。tuple
vs の速度を区別できませんでしたlist
。
テストする値が、ループ内でリテラルを作成するのではなく、関数のグローバル変数にキャッシュされたset
場合、Python 2でも毎回勝ちました。
これらの結果は、Core i7上の64ビットCPythonに適用されます。
from datetime import datetime
listA = range(10000000)
setA = set(listA)
tupA = tuple(listA)
#Source Code
def calc(data, type):
start = datetime.now()
if data in type:
print ""
end = datetime.now()
print end-start
calc(9999, listA)
calc(9999, tupA)
calc(9999, setA)
3つすべての10回の反復を比較した後の出力: 比較
セットはより高速であり、2つのセットがあるとしましょう。
set1 = {"Harry Potter", "James Bond", "Iron Man"}
set2 = {"Captain America", "Black Widow", "Hulk", "Harry Potter", "James Bond"}
2つのセットを簡単に結合できます。
set3 = set1.union(set2)
両方に共通するものを見つけます。
set3 = set1.intersection(set2)
両方の違いを確認してください:
set3 = set1.difference(set2)
そして、はるかに!試してみるだけで楽しい!さらに、2つのリスト内の異なる値または2つのリスト内の共通の値を処理する必要がある場合は、リストをセットに変換することを好み、多くのプログラマーがそのようにします。それがあなたを助けることを願っています:-)