web-dev-qa-db-ja.com

pythonリスト関数の実行時の複雑さはどれくらいですか?

私はpythonこのような関数を書いていました

_def foo(some_list):
   for i in range(0, len(some_list)):
       bar(some_list[i], i)
_

それが呼ばれたように

_x = [0, 1, 2, 3, ... ]
foo(x)
_

リストのインデックスアクセスはO(1)であると想定していましたが、大きなリストの場合、これが予想よりも大幅に遅いことに驚きました。

私の質問は、pythonリストがどのように実装されているか、そして以下のランタイムの複雑さは何ですか?

  • インデックス作成:_list[x]_
  • 最後からポップ:list.pop()
  • 最初からポップ:list.pop(0)
  • リストの拡張:list.append(x)

追加のクレジット、スプライシングまたは任意のポップ。

43
Marquis Wang

python wiki の非常に詳細な表)があり、質問に答えます。

ただし、特定の例では、enumerateを使用してループ内の反復可能オブジェクトのインデックスを取得する必要があります。そのようです:

for i, item in enumerate(some_seq):
    bar(item, i)
35
SilentGhost

答えは「未定義」です。 Python言語は、基礎となる実装を定義していません。あなたが興味を持っているかもしれないメーリングリストのスレッドへのリンクがいくつかあります。

また、ループを記述するよりPython的な方法は次のようになります。

def foo(some_list):
   for item in some_list:
       bar(item)
8
anthony

リストは確かにO(1) to index-リストは比例割り当て超過のベクトルとして実装されているため、期待どおりに実行されます。このコードが予想よりも遅いことがわかった理由として考えられます「range(0, len(some_list))」の呼び出しです。

range()は、指定されたサイズの新しいリストを作成します。したがって、some_listに1,000,000のアイテムがある場合、最初に新しい100万のアイテムリストを作成します。この動作はpython3で変更され(範囲はイテレータです)、それに相当するpython2は xrange 、またはあなたの場合には enumerate

6
Brian

インデックスと値が必要な場合は、enumerateを使用します。

for idx, item in enumerate(range(10, 100, 10)):
    print idx, item
3
Maxim Kim

Pythonは実際には配列だけをリストします。したがって、

インデックス作成にはO(1)が必要です

ポップとアペンドの場合は、ドキュメントに従ってO(1)にする必要があります

詳細については、次のリンクを確認してください。

http://dustycodes.wordpress.com/2012/03/31/pythons-data-structures-complexity-analysis/

1
codersofthedark