Pythonのリストでsort()
を呼び出すと、cmp=f
を渡すと並べ替えが遅くなります。 reverse=True
を渡すことは、ソートの効率に何らかの影響を及ぼします(または、ソートしないでソートすることと同じです)?Pythonでリストをソートすると効率に影響を与える場合、reverse = Trueを渡しますか?
答えて
sort()
メソッドはネイティブです。つまり、Pythonではなくホスト言語で実装されています。 cmp
引数に関数を渡すと、ネイティブ実装はその関数を呼び出して各繰り返しでPythonコードを実行します。それはパフォーマンスのヒットから来ています。
一方、引数にTrue
を渡しても、ネイティブアルゴリズムは逆にアイテムをソートするよう指示します。 cmp
が設定されていない場合は、ネイティブコードのみが含まれるため、パフォーマンスは平文sort()
に匹敵するはずです。
もちろん、ベンチマークによって確実にわかります。
reverse=True
のためにスローダウンが発生していないと推測します。その結果は、途中で逆の決定で単純に構築できるためです。 (おかげでダンカンに)正確にベンチマークすると、この推測が裏付けされています。私はこのテストを数回繰り返し、異なるサイズのリスト(N = 10**3, 10**4, 10**5
)とし、一貫性のある結果を受け取った
In [18]: import random
In [57]: x = range(1000)
In [58]: random.shuffle(x)
In [59]: %timeit sorted(x)
1000 loops, best of 3: 341 us per loop
In [54]: x = range(1000)
In [55]: random.shuffle(x)
In [56]: %timeit sorted(x, reverse = True)
1000 loops, best of 3: 344 us per loop
。
私のベンチマークから、わずかな差があるように表示されます(私のマシン上)で
import timeit
setup = """
import random
random.seed(1)
l = range(10000)
random.shuffle(l)
"""
run1 = """
sorted(l)
"""
run2 = """
sorted(l, reverse=True)
"""
n1 = timeit.timeit(run1, setup, number=10000)
n2 = timeit.timeit(run2, setup, number=10000)
print n1, n2
print (n2/n1 - 1)*100,"%"
結果:
38.8531708717 41.2889549732
6.26920286513 %
同じ実行が、1000個の要素のリストについては:
2.80148005486 2.74061703682
-2.17253083528 %
# ...another round...
2.90553498268 2.86594104767
-1.36270722083 %
毎回同じリストをソートすると、ソートの時間はデータの分布に依存するため、違いはありません。 –
驚くべきことに、リストを逆ソートするのに時間がかかります。他の答えはすでにこれを素晴らしいベンチマークで示しています。私はソースに見て、explanation in listobject.c
が見つかりました:
/* Reverse sort stability achieved by initially reversing the list,
applying a stable forward sort, then reversing the final result. */
if (reverse) {
if (keys != NULL)
reverse_slice(&keys[0], &keys[saved_ob_size]);
reverse_slice(&saved_ob_item[0], &saved_ob_item[saved_ob_size]);
}
だから、ソートされた出力を取得するには、リストはその後、並べ替えの前に逆転ソートし、最後に再び逆転されます。リストを逆にすると、O(n)の操作になるので、これ以上の支払いをするほどリストは長くなります。
これはとにかくカスタムキー機能を構築している場合は、あなたが直接それを否定することで、大きなリストのための時間を節約することができますことを示唆している:
very_long_list.sort(key=lambda x, y: -cmp(x, y))
代わりreversed=True
を使用する:
very_long_list.sort(key=lambda x, y: cmp(x, y), reverse=True)
この場合、もちろん、key=cmp
を直接2番目のケースで渡すことができるので、ラムダ関数を介して余分な呼び出しを保存します。しかし、あなたがより大きな表現をしているなら、これはうまくいくかもしれません。list.sort
からcmp
引数とsorted
組み込み関数はPython 2にXを非推奨となり、もはやあなたが気づいているように、なぜなら彼らは与えるパフォーマンスの低下、3 Xに許可されていることを
比較関数を単に否定すると、逆ソートが安定しなくなることに注意してください。そのため、Pythonは安定性を維持するために逆/ソート/逆シャッフルを行います。 – Duncan
+1はコード探査を行っています。私はまだタールボールをダウンロードしていた... ;-) – GaretJax
@ダンカン:本当ですか?私はそれが本当であるとは思わない:定義 'sort(key = f)'は、 'f'が否定された比較関数である場合を含め、' f'に対して安定です。それはcpythonコードがダブルリバースしてパフォーマンスの理由から比較関数の結果を否定する必要がないように見えますが、正しいことができます。間違っているのは、通常のキーで安定してソートした後、ソートする前に元に戻すことなく元に戻すことです。 – sdcvvc
注意。代わりに、key
引数を使用してカスタム並べ替え順序を定義する必要があります。
本当に、2.xのすべてで廃止予定ですか?私には2.3日から2.4日の本があり、それは説明され奨励されています。 – jrdioko
細かく、2.3/2.4に固執してください。 –
- 1. ウェブサイトのフロントページに影響を与えるステートメントの場合は?
- 2. divの拡張効果に影響を与えますか?
- 3. Outlook Gmail Webviewerに影響を与える
- 4. レイアウトに影響を与えるCSSサブメニュー
- 5. プロパティに影響を与えるメソッドと値を返すメソッド
- 6. 更新プログラムの場合....行に影響を与えない場合は、ロックが作成されますか?
- 7. Python実行中のプログラムに影響を与える方法
- 8. 影響を与える要因
- 9. "条件が" OpenCLのカーネル実行のパフォーマンスに影響を与える場合は?
- 10. ダミー変数に影響を与えずにリストから削除する
- 11. console.debug()は、リリースモードでのネイティブパフォーマンスに影響を与えますか?
- 12. li:hover>影響を与える他のリスト項目
- 13. Silverlight:アセンブリバージョンがApplicationSettengsに与える影響
- 14. Trusted_Connection = trueとSQL Server認証を使用する場合、これはパフォーマンスに影響しますか?
- 15. は、背景色に影響を与え
- 16. インラインフレックスを子供に影響を与えるように表示しますか?
- 17. 多すぎると、ウェブサイトのパフォーマンスに悪影響を与えますか?
- 18. ある値を更新するPython SQLite他に影響を与えない
- 19. TDEの有効化がデータベースのパフォーマンスに与える影響は何ですか?
- 20. Firebaseコンソールのクラッシュリプレットに影響を与えるインスタンスとユーザとは何ですか?
- 21. System.out.println()はコード効率に影響しますか?
- 22. sp_updatestatsがSQLに与える影響はありますか?
- 23. will_many:RoRに大きなパフォーマンス上の影響を与えますか?
- 24. catch節がパフォーマンスに影響を与えますか?
- 25. dns-prefetchingはパフォーマンスにマイナスの影響を与えますか?
- 26. なぜgroovycはセキュリティマネージャーに影響を与えますか?
- 27. NSMutableArrayが別のNSMutableArrayに影響を与えていますか?
- 28. MediaWiki - Print.cssに影響を与えずにCommon.cssを変更する
- 29. ピンチをズームするにはscrollView内のUIImageViewに影響を与えますか?
- 30. ローカルクローンがGitに与える影響は何ですか?
興味深く便利な質問の場合は+ 0.75、*影響*という単語の適切な使用の場合は+ 0.25です。 –