Python 查找与列表中的值最接近的项的索引,该列表为';没有完全分类

Python 查找与列表中的值最接近的项的索引,该列表为';没有完全分类,python,list,search,Python,List,Search,例如,我的清单是: [25.75443, 26.7803, 25.79099, 24.17642, 24.3526, 22.79056, 20.84866, 19.49222, 18.38086, 18.0358, 16.57819, 15.71255, 14.79059, 13.64154, 13.09409, 12.18347, 11.33447, 10.32184, 9.544922, 8.813385, 8.181152, 6.983734, 6.048035, 5.505096, 4.

例如,我的清单是:

[25.75443, 26.7803, 25.79099, 24.17642, 24.3526, 22.79056, 20.84866, 19.49222, 18.38086, 18.0358, 16.57819, 15.71255, 14.79059, 13.64154, 13.09409, 12.18347, 11.33447, 10.32184, 9.544922, 8.813385, 8.181152, 6.983734, 6.048035, 5.505096, 4.65799]
我正在寻找最接近
11.5
的值的索引。我尝试过其他方法,如二进制搜索和左对分,但它们不起作用


我无法对该数组进行排序,因为该值的索引将用于类似的数组,以获取该索引处的值。

如何:将两个列表压缩,然后对结果进行排序?

尝试以下操作:

min(range(len(a)), key=lambda i: abs(a[i]-11.5))
例如:

>>> a = [25.75443, 26.7803, 25.79099, 24.17642, 24.3526, 22.79056, 20.84866, 19.49222, 18.38086, 18.0358, 16.57819, 15.71255, 14.79059, 13.64154, 13.09409, 12.18347, 11.33447, 10.32184, 9.544922, 8.813385, 8.181152, 6.983734, 6.048035, 5.505096, 4.65799]
>>> min(range(len(a)), key=lambda i: abs(a[i]-11.5))
16
或获取索引和值:

>>> min(enumerate(a), key=lambda x: abs(x[1]-11.5))
(16, 11.33447)

如果无法对数组进行排序,则无法快速找到最接近的项-必须迭代所有项

有一个解决方法,但这是一个相当大的工作量:编写一个排序算法,对数组进行排序,同时更新第二个数组,告诉您在对数组排序之前该条目在哪里

这样,您可以使用二进制搜索查找最近条目的索引,然后使用此索引使用“索引数组”查找原始索引

[编辑]使用
zip()
,这非常容易实现:

 array_to_sort = zip( original_array, range(len(original_array)) )
 array_to_sort.sort( key=i:i[0] )

现在,您可以使用二进制搜索值(使用
项[0]
)<代码>项目[1]将为您提供原始索引。

遍历所有项目只是线性的。如果要对数组进行排序,情况会更糟


我认为保留一个额外的
deltax
(到目前为止的最小差异)和
idx
(该元素的索引)并在列表中循环一次没有问题。

请记住,如果空间不重要,您可以通过创建已排序索引的二级列表来对任何列表进行排序,而无需移动内容

还要记住,如果只进行一次查找,那么只需遍历列表O(n)中的每个元素。(如果多次,您可能希望稍后进行排序以提高效率)


如果a已经是一个数组,则可以执行相应的转换。

如果您多次搜索一个长列表,那么
min
的缩放效果非常差(O(n^2),如果您将一些搜索附加到搜索列表中,我想)

平分是你的朋友。这是我的解决办法。它的比例为O(n*log(n)):

将输出:

Closest to   1.0 : rank= 0 num= 1.33447 index=16
Closest to 100.0 : rank=25 num=26.78030 index= 1
Closest to  15.0 : rank=12 num=14.79059 index=12
Closest to  15.6 : rank=13 num=15.71255 index=11
Closest to   8.0 : rank= 5 num= 8.18115 index=20
以及:

输出:

Closest to 100.0 : rank=25 num=99.90000 index=25

可能重复@Jean-FrançoisCorbett这个问题怎么可能是另一个问题的重复。这个问题比较老。@QiuYU因为@GhassenLouhaichi在这篇文章中没有链接。在发布自动注释之前,请仔细考虑。
def find_nearray(数组,值):array=np.asarray(数组);idx=(np.abs(array-value)).argmin();返回idx执行得更快(受启发),或者只需使用
cl.closest(target)
,对吗?谢谢你的代码!是的,没错!很高兴你喜欢它。由于我们无法知道列表中的哪些子列表已排序,所以对分没有帮助,我们必须触及每个元素。@Jan我想你是对的,我将修改措辞
a = [25.75443, 26.7803, 25.79099, 24.17642, 24.3526, 22.79056, 20.84866,
     19.49222, 18.38086, 18.0358, 16.57819, 15.71255, 14.79059, 13.64154,
     13.09409, 12.18347, 1.33447, 10.32184, 9.544922, 8.813385, 8.181152,
     6.983734, 6.048035, 5.505096, 4.65799]
targets = [1.0, 100.0, 15.0, 15.6, 8.0]
cl = Closest(a)
for x in targets:
    rank = cl.rank(x)
    print("Closest to %5.1f : rank=%2i num=%8.5f index=%2i " % (x, rank,
        cl.nums[rank], cl.closest(x)))
Closest to   1.0 : rank= 0 num= 1.33447 index=16
Closest to 100.0 : rank=25 num=26.78030 index= 1
Closest to  15.0 : rank=12 num=14.79059 index=12
Closest to  15.6 : rank=13 num=15.71255 index=11
Closest to   8.0 : rank= 5 num= 8.18115 index=20
cl.append(99.9)
x = 100.0
rank = cl.rank(x)
print("Closest to %5.1f : rank=%2i num=%8.5f index=%2i " % (x, rank,
    cl.nums[rank], cl.closest(x)))
Closest to 100.0 : rank=25 num=99.90000 index=25