len()
組み込み関数Pythonのコストはいくらですか? (リスト/タプル/文字列/辞書)
O(1)(一定の時間、要素の実際の長さに依存しない-非常に高速)言及したすべての型に加えて、set
およびarray.array
などのその他のものです。
これらのデータ型でlen()を呼び出すことは、O(1) in CPython で、Python言語の最も一般的な実装です。 CPythonのさまざまな関数のアルゴリズムの複雑さを提供するテーブルへのリンクを次に示します。
これらのオブジェクトはすべて、独自の長さを追跡します。長さを抽出する時間は小さく(big-O表記のO(1))、大部分[Cの用語ではなくPythonの用語で書かれた大まかな説明)で構成されます。辞書とそれをオブジェクトの__len__
メソッドを検索し、それを呼び出すbuilt_in len関数にディスパッチします...しなければならないのはreturn self.length
だけです
以下の測定値は、よく使用されるデータ構造のlen()
がO(1)であることの証拠を提供します。
timeit
に関する注意:-s
フラグが使用され、2つの文字列がtimeit
に渡されると、最初の文字列は一度だけ実行され、時間は計測されません。
$ python -m timeit -s "l = range(10);" "len(l)"
10000000 loops, best of 3: 0.0677 usec per loop
$ python -m timeit -s "l = range(1000000);" "len(l)"
10000000 loops, best of 3: 0.0688 usec per loop
$ python -m timeit -s "t = (1,)*10;" "len(t)"
10000000 loops, best of 3: 0.0712 usec per loop
$ python -m timeit -s "t = (1,)*1000000;" "len(t)"
10000000 loops, best of 3: 0.0699 usec per loop
$ python -m timeit -s "s = '1'*10;" "len(s)"
10000000 loops, best of 3: 0.0713 usec per loop
$ python -m timeit -s "s = '1'*1000000;" "len(s)"
10000000 loops, best of 3: 0.0686 usec per loop
$ python -mtimeit -s"d = {i:j for i,j in enumerate(range(10))};" "len(d)"
10000000 loops, best of 3: 0.0711 usec per loop
$ python -mtimeit -s"d = {i:j for i,j in enumerate(range(1000000))};" "len(d)"
10000000 loops, best of 3: 0.0727 usec per loop
$ python -mtimeit -s"import array;a=array.array('i',range(10));" "len(a)"
10000000 loops, best of 3: 0.0682 usec per loop
$ python -mtimeit -s"import array;a=array.array('i',range(1000000));" "len(a)"
10000000 loops, best of 3: 0.0753 usec per loop
$ python -mtimeit -s"s = {i for i in range(10)};" "len(s)"
10000000 loops, best of 3: 0.0754 usec per loop
$ python -mtimeit -s"s = {i for i in range(1000000)};" "len(s)"
10000000 loops, best of 3: 0.0713 usec per loop
$ python -mtimeit -s"from collections import deque;d=deque(range(10));" "len(d)"
100000000 loops, best of 3: 0.0163 usec per loop
$ python -mtimeit -s"from collections import deque;d=deque(range(1000000));" "len(d)"
100000000 loops, best of 3: 0.0163 usec per loop
lenはO(1)です。これは、RAMにリストがテーブルとして格納されるため(一連の連続したアドレス)。テーブルがいつ停止するかを知るには、長さと開始点の2つのことが必要です。 len()がO(1)である理由は、コンピューターが値を保存するため、ルックアップするだけです。
リストのサイズに依存するPythonのlen()を考えてきたので、複数回使用する場合は常に変数に長さを格納します。しかし、今日、デバッグ中にリストオブジェクトの__len__属性に気づいたので、len()はそれをフェッチするだけである必要があり、複雑なO(1)になります。だから誰かがすでにそれを尋ねて、この投稿に出会ったかどうかをグーグルで調べた。