62

float の Python リストで最小項目のインデックスを見つけるにはどうすればよいですか? それらが整数の場合、私は単純に次のようにします。

minIndex = myList.index(min(myList))

ただし、フロートのリストを使用すると、次のエラーが発生します。これは、フロートの等価性の比較がかなり不安定であるためだと思います。

ValueError: 0.13417985135 is not in list

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

4

4 に答える 4

107

私は使うだろう:

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

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

于 2012-11-09T01:54:18.760 に答える
74

リストを効果的にスキャンして最小値を見つけ、次に再度スキャンしてインデックスを見つけます。両方を一度に行うことができます。

from operator import itemgetter
min(enumerate(a), key=itemgetter(1))[0] 
于 2012-11-09T01:56:19.183 に答える
44

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

import numpy as np
np.argmin(myList)

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

于 2014-07-11T11:40:44.580 に答える
18

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

python2.7を使用してOS-X10.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可能な限り遅くするために、意図的に最小のアイテムをリストの最後に配置していることに注意してください。ここでの2回の反復の回答と、1回の反復の回答がどのNで競合するかを確認するのは興味深いことです。

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

于 2012-11-09T02:09:56.500 に答える