web-dev-qa-db-ja.com

Pythonセットとリスト

Pythonでは、どのデータ構造がより効率的/高速ですか?順序が私にとって重要ではなく、とにかく重複をチェックすると仮定すると、PythonセットはPythonリストよりも遅いですか?

160
Mantas Vidutis

それはあなたがそれで何をしようとしているかに依存します。

セットにオブジェクトが存在するかどうかを判断する場合(x in sのように)、セットは非常に高速ですが、コンテンツを反復する場合はリストよりも遅くなります。

timeit module を使用して、状況により速い方を確認できます。

196

値を反復処理するだけの場合、リストはセットよりもわずかに高速です。

ただし、アイテムがリストに含まれているかどうかを確認する場合、セットはリストよりもかなり高速です。ただし、一意のアイテムのみを含めることができます。

タプルは、その不変性を除いて、リストとほぼ同じ方法で機能することがわかります。

反復

>>> 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
135
Ellis Percival

リストのパフォーマンス:

>>> 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番目の違いは、セット内の要素が一意でなければならないことです。

定義によりset。 [ python | wiki ]。

>>> x = set([1, 1, 2, 2, 3, 3])
>>> x
{1, 2, 3}
7
user2601995

Setほぼ瞬時に「含む」チェックにより勝ちます: https://en.wikipedia.org/wiki/Hash_table

List実装:通常、配列、金属に近い低レベル、反復および要素インデックスによるランダムアクセスに適しています。

Set実装: https://en.wikipedia.org/wiki/Hash_table 、リストで反復しません、ただし、キーからhashを計算して要素を見つけるため、キー要素の性質とハッシュ関数に依存します。 dictに使用されるものに似ています。要素が非常に少ない(<5)場合、listの方が高速になる可能性があります。要素数が多いほど、setの包含チェックのパフォーマンスが向上します。また、要素の追加と削除も高速です。

NOTElistが既にソートされている場合、listの検索は非常に高速になりますが、通常はsetは、containsチェックの方が高速で単純です。

3

ユースケースが存在の参照または検索に制限されているSet実装と、ユースケースで反復の実行が必要なTuple実装をお勧めします。リストは低レベルの実装であり、かなりのメモリオーバーヘッドが必要です。

0
user7763294

tl; dr

データ構造(DS)は、基本的には入力を取得処理する、および出力を戻す

特定のケースでは、一部のデータ構造は他のデータ構造よりも便利です。したがって、どちらの(DS)がより効率的/高速であるかを尋ねることは非常に不公平です。ナイフとフォークのどちらがより効率的かを尋ねるようなものです。すべては状況次第です。

リスト

リストは、可変シーケンス通常、同種のアイテムのコレクションを格納するために使用されます

セット

セットオブジェクトは、個別のハッシュ可能なオブジェクトの順序付けられていないコレクションです。一般的には、メンバーシップのテスト、シーケンスからの重複の削除、交差、結合、差、対称差などの数学演算の計算に使用されます。

使用法

いくつかの答えから、値を反復処理する場合、リストがセットよりも非常に高速であることは明らかです。一方、セットがリストに含まれているかどうかをチェックする場合、セットはリストよりも高速です。したがって、あなたが言える唯一のことは、リストは特定の操作のセットよりも優れているということです。

0
lmiguelvargasf