62

如何在 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-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    

大卫沃尔弗的回答:

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尽可能慢。有趣的是,看看迭代一次的答案将与我们在这里的迭代两次答案竞争。

当然,速度并不是一切,而且在大多数情况下,它甚至不值得担心......选择最容易阅读的一个,除非这是您代码中的性能瓶颈(然后在您的典型现实世界中进行分析数据——最好在你的目标机器上)。

于 2012-11-09T02:09:56.500 回答