Python floatsのリストで最小アイテムのインデックスを見つけるにはどうすればよいですか?整数の場合、単純に行います:
minIndex = myList.index(min(myList))
ただし、フロートのリストでは、次のエラーが発生します。フロートの等値比較はかなり曖昧だからです。
ValueError: 0.13417985135 is not in list
これで、リストをスクロールして各項目を比較し、<(最小+ 0.0000000000001)および>(最小-0.0000000000001)であるかどうかを確認できることがわかりましたが、それはやや面倒です。フロートのリストで最小のアイテムのインデックスを見つけるためのよりエレガントな(できれば組み込みの)方法はありますか?
リストを効果的に1回スキャンして最小値を見つけ、それから再度スキャンしてインデックスを見つけます。両方を一度に実行できます。
from operator import itemgetter
min(enumerate(a), key=itemgetter(1))[0]
私は使うだろう:
val, idx = min((val, idx) for (idx, val) in enumerate(my_list))
次に、val
が最小値になり、idx
がそのインデックスになります。
Numpy配列に対するargminメソッドの使用。
import numpy as np
np.argmin(myList)
ただし、これは最速の方法ではありません。コンピューター上のOPの回答よりも3倍遅いです。もっとも簡潔なものかもしれません。
いくつかの観点からここにいくつかのタイミングを置く価値があると思います。
すべてのタイミングは、python2.7を使用してOS-X 10.5.8で行われました
ジョン・クレメントの答え:
python -m timeit -s 'my_list = range(1000)[::-1]; from operator import itemgetter' 'min(enumerate(my_list),key=itemgetter(1))'
1000 loops, best of 3: 239 usec per loop
David Woleverの答え:
python -m timeit -s 'my_list = range(1000)[::-1]' 'min((val, idx) for (idx, val) in enumerate(my_list))
1000 loops, best of 3: 345 usec per loop
OPの答え:
python -m timeit -s 'my_list = range(1000)[::-1]' 'my_list.index(min(my_list))'
10000 loops, best of 3: 96.8 usec per loop
.index
を可能な限り遅くするために、意図的に最小の項目をリストの最後に配置していることに注意してください。反復Nの回答が競合するようになるNで、ここでの反復2回の回答と比較すると興味深いでしょう。
もちろん、速度はすべてではありませんそしてほとんどの場合、心配する価値さえありません...これがコードのパフォーマンスのボトルネックでない限り、読みやすいものを選択してください(そして典型的な実世界のデータ(できればターゲットマシン)のプロファイル)。