Python: Find index of minimum item in list of floa

2019-02-01 04:59发布

问题:

This question already has an answer here:

  • Getting the index of the returned max or min item using max()/min() on a list 21 answers

How can I find the index of the minimum item in a Python list of floats? If they were integers, I would simply do:

minIndex = myList.index(min(myList))

However, with a list of floats I get the following error, I assume because float equality comparison is rather iffy.

ValueError: 0.13417985135 is not in list

Now, I know that I could simply scroll through the list and compare each item to see whether it is < (min + 0.0000000000001) and > (min - 0.0000000000001), but that is kinda messy. Is there a more elegant (preferably built-in) way to find the index of the smallest item in a list of floats?

回答1:

You're effectively scanning the list once to find the min value, then scanning it again to find the index, you can do both in one go:

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


回答2:

I would use:

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

Then val will be the minimum value and idx will be its index.



回答3:

Use of the argmin method for numpy arrays.

import numpy as np
np.argmin(myList)

However, it is not the fastest method: it is 3 times slower than OP's answer on my computer. It may be the most concise one though.



回答4:

I think it's worth putting a few timings up here for some perspective.

All timings done on OS-X 10.5.8 with python2.7

John Clement's answer:

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's answer:

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's answer:

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

Note that I'm purposefully putting the smallest item last in the list to make .index as slow as it could possibly be. It would be interesting to see at what N the iterate once answers would become competitive with the iterate twice answer we have here.

Of course, speed isn't everything and most of the time, it's not even worth worrying about ... choose the one that is easiest to read unless this is a performance bottleneck in your code (and then profile on your typical real-world data -- preferably on your target machines).