Pythonでは、どのデータ構造がより効率的/高速ですか?順序が私にとって重要ではなく、とにかく重複をチェックすると仮定すると、PythonセットはPythonリストよりも遅いですか?
それはあなたがそれで何をしようとしているかに依存します。
セットにオブジェクトが存在するかどうかを判断する場合(x in s
のように)、セットは非常に高速ですが、コンテンツを反復する場合はリストよりも遅くなります。
timeit module を使用して、状況により速い方を確認できます。
値を反復処理するだけの場合、リストはセットよりもわずかに高速です。
ただし、アイテムがリストに含まれているかどうかを確認する場合、セットはリストよりもかなり高速です。ただし、一意のアイテムのみを含めることができます。
タプルは、その不変性を除いて、リストとほぼ同じ方法で機能することがわかります。
反復
>>> 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
ほぼ瞬時に「含む」チェックにより勝ちます: https://en.wikipedia.org/wiki/Hash_table
List実装:通常、配列、金属に近い低レベル、反復および要素インデックスによるランダムアクセスに適しています。
Set実装: https://en.wikipedia.org/wiki/Hash_table 、リストで反復しません、ただし、キーからhashを計算して要素を見つけるため、キー要素の性質とハッシュ関数に依存します。 dictに使用されるものに似ています。要素が非常に少ない(<5)場合、list
の方が高速になる可能性があります。要素数が多いほど、set
の包含チェックのパフォーマンスが向上します。また、要素の追加と削除も高速です。
NOTE:list
が既にソートされている場合、list
の検索は非常に高速になりますが、通常はset
は、containsチェックの方が高速で単純です。
ユースケースが存在の参照または検索に制限されているSet実装と、ユースケースで反復の実行が必要なTuple実装をお勧めします。リストは低レベルの実装であり、かなりのメモリオーバーヘッドが必要です。
データ構造(DS)は、基本的には入力を取得、処理する、および出力を戻す。
特定のケースでは、一部のデータ構造は他のデータ構造よりも便利です。したがって、どちらの(DS)がより効率的/高速であるかを尋ねることは非常に不公平です。ナイフとフォークのどちらがより効率的かを尋ねるようなものです。すべては状況次第です。
リストは、可変シーケンス、通常、同種のアイテムのコレクションを格納するために使用されます 。
セットオブジェクトは、個別のハッシュ可能なオブジェクトの順序付けられていないコレクションです。一般的には、メンバーシップのテスト、シーケンスからの重複の削除、交差、結合、差、対称差などの数学演算の計算に使用されます。
いくつかの答えから、値を反復処理する場合、リストがセットよりも非常に高速であることは明らかです。一方、セットがリストに含まれているかどうかをチェックする場合、セットはリストよりも高速です。したがって、あなたが言える唯一のことは、リストは特定の操作のセットよりも優れているということです。