【问题标题】:Python - Take the index of slightly different valuesPython - 取略有不同值的索引
【发布时间】:2021-09-30 16:24:37
【问题描述】:

我有兴趣获取另一个列表中包含的值的通用列表“L”的索引,称为“目标”。看起来很简单,但是如果我的目标列表的值略有不同,我不知道如何考虑这种差异。例如,如果在“L”列表中我的值为 1.9,而在目标中的值为 1.89,我想采用 1.9 的索引,因为它接近 1.89。我该怎么做?

L = [0.4,0.5,0.55,0.78,0.9,1.1,1.8,1.9]
target = [0.55,0.9,1.09,1.89]
index = []
for i in target:
    index.append(L.index(i))
print(index)

预期输出:[2,4,5,7]

提前致谢!

【问题讨论】:

  • L 是否总是排序的?
  • 什么是接近?你有门槛吗?

标签: python list indexing


【解决方案1】:

你可以使用math.isclose:

import math

L = [0.4, 0.5, 0.55, 0.78, 0.9, 1.1, 1.8, 1.9]
target = [0.55, 0.9, 1.09, 1.89]

index = [i for i, e in enumerate(L) if any(math.isclose(e, t, abs_tol=0.05) for t in target)]
print(index)

输出

[2, 4, 5, 7]

上述方法的计算复杂度为O(nm),其中nm是列表L和目标的长度。此外,您可以在O((n + m)logn) 中对target 进行排序:

def is_close_to_any(e, tgt):
    import bisect
    """Finds if any values are close in O(log n)"""
    point_before_insertion = max(0, bisect.bisect(tgt, e) - 1)

    # find two closest points
    values = tgt[point_before_insertion:point_before_insertion + 2]

    # return if any of the two is close
    return any(math.isclose(e, t, abs_tol=0.05) for t in values)


target = sorted(target)
index = [i for i, e in enumerate(L) if is_close_to_any(e, target)]
print(index)

输出 (使用排序和二分法)

[2, 4, 5, 7]

【讨论】:

    【解决方案2】:

    如果L已排序,则可以使用bisect查找最接近的值:

    from bisect import bisect
    
    def find_closest(L, x):
        index = bisect(L, x)
    
        if index == 0: return 0
        elif index == len(L): return index-1
        elif x - L[index-1] > L[index] - x: return index
        else: return index-1
    
    [find_closest(L, x) for x in target]
    # [2, 4, 5, 7]
    

    【讨论】:

      【解决方案3】:

      Python 的min 与压缩值和索引之间的abs 距离。

      L = [0.4,0.5,0.55,0.78,0.9,1.1,1.8,1.9]
      target = [0.55,0.9,1.09,1.89]
       
      [min(zip(L, range(len(L))), key=lambda x:abs(x[0]-i))[1] for i in target]
      

      输出

      [2, 4, 5, 7]
      

      【讨论】:

        猜你喜欢
        • 2012-04-24
        • 1970-01-01
        • 1970-01-01
        • 2015-04-24
        • 1970-01-01
        • 1970-01-01
        • 2013-09-28
        • 2022-10-13
        • 2016-08-03
        相关资源
        最近更新 更多