Ответ 1
Вы эффективно просматриваете список один раз, чтобы найти значение min, а затем снова сканируете его, чтобы найти индекс, вы можете сделать это за один раз:
from operator import itemgetter
min(enumerate(a), key=itemgetter(1))[0]
Как я могу найти индекс минимального элемента в списке плавающих Python? Если бы они были целыми числами, я бы просто сделал:
minIndex = myList.index(min(myList))
Однако, со списком поплавков, я получаю следующую ошибку, я предполагаю, потому что сравнение равенства поплавка довольно неплохо.
ValueError: 0.13417985135 is not in list
Теперь я знаю, что могу просто прокрутить список и сравнить каждый элемент, чтобы увидеть, (мин + 0,0000000000001) и > (мин - 0,0000000000001), но это бесполезно. Есть ли более элегантный (желательно встроенный) способ найти индекс наименьшего элемента в списке поплавков?
Вы эффективно просматриваете список один раз, чтобы найти значение min, а затем снова сканируете его, чтобы найти индекс, вы можете сделать это за один раз:
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
будет его индексом.
Использование метода argmin для массивов numpy.
import numpy as np
np.argmin(myList)
Однако, это не самый быстрый метод: он в 3 раза медленнее, чем ответ OP на моем компьютере. Это может быть самым кратким, хотя.
Я думаю, что стоит потратить несколько минут на некоторые перспективы.
Все тайминги, выполненные в OS-X 10.5.8 с помощью python2.7
Ответ Джона Клемента:
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
Дэвид Волевер отвечает:
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 итерации один раз ответы станут конкурентными с повторным итерационным ответом, который мы имеем здесь.
Конечно, скорость - это не все, и большую часть времени это даже не стоит беспокоиться... выберите тот, который проще всего читать, если это не является узким местом в вашем коде (а затем профиль на ваших типичных реальных данных - желательно на ваших целевых машинах).