web-dev-qa-db-ja.com

Python:フロートのリストで最小アイテムのインデックスを検索

Python floatsのリストで最小アイテムのインデックスを見つけるにはどうすればよいですか?整数の場合、単純に行います:

minIndex = myList.index(min(myList))

ただし、フロートのリストでは、次のエラーが発生します。フロートの等値比較はかなり曖昧だからです。

ValueError: 0.13417985135 is not in list

これで、リストをスクロールして各項目を比較し、<(最小+ 0.0000000000001)および>(最小-0.0000000000001)であるかどうかを確認できることがわかりましたが、それはやや面倒です。フロートのリストで最小のアイテムのインデックスを見つけるためのよりエレガントな(できれば組み込みの)方法はありますか?

39
thornate

リストを効果的に1回スキャンして最小値を見つけ、それから再度スキャンしてインデックスを見つけます。両方を一度に実行できます。

from operator import itemgetter
min(enumerate(a), key=itemgetter(1))[0] 
55
Jon Clements

私は使うだろう:

val, idx = min((val, idx) for (idx, val) in enumerate(my_list))

次に、valが最小値になり、idxがそのインデックスになります。

67
David Wolever

Numpy配列に対するargminメソッドの使用。

import numpy as np
np.argmin(myList)

ただし、これは最速の方法ではありません。コンピューター上のOPの回答よりも3倍遅いです。もっとも簡潔なものかもしれません。

21
AlexP

いくつかの観点からここにいくつかのタイミングを置く価値があると思います。

すべてのタイミングは、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回の回答と比較すると興味深いでしょう。

もちろん、速度はすべてではありませんそしてほとんどの場合、心配する価値さえありません...これがコードのパフォーマンスのボトルネックでない限り、読みやすいものを選択してください(そして典型的な実世界のデータ(できればターゲットマシン)のプロファイル)。

13
mgilson