python - 在循环有序列表中找到最接近值的优雅方法

标签 python

给定一个已排序列表,例如[1.1, 2.2, 3.3]和一个边界值,例如math.pi*2,返回[0 - math.pi*2)

中任何给定值的最接近值

该函数应返回值的索引,以便 f(1.2) 返回 0f(2.1) 返回 1f(6.0) 应该在 math.pi*2 处回绕并返回 0,更接近 1.1比 3.3 给定的边界值。为了完全明确,这个函数也应该在低端环绕,这样 f(1.0, [5.0, 6.0], bound = math.pi*2) 返回 1

用例是将以弧度为单位的任意角度映射到列表中最近的现有有效角度。我用 bisect 在 python 中写过几次这种函数,但代码总是以冒犯我的审美感告终。高复杂性和边缘情况的数量似乎与功能的直观简单性不成比例。因此,我想问是否有人可以在效率和优雅方面提出一个令人满意的实现。

最佳答案

这是一个更优雅的方法。通过环绕数字线来消除边缘情况:

from bisect import bisect_right

def circular_search(points, bound, value):
    ##
    ## normalize / sort input points to [0, bound)
    points = sorted(list(set([i % bound for i in points])))
    ##
    ## normalize search value to [0, bound)
    value %= bound
    ##
    ## wrap the circle left and right
    ext_points = [i-bound for i in points] + points + [i+bound for i in points]
    ##
    ## identify the "nearest not less than" point; no
    ## edge cases since points always exist above & below
    index = bisect_right(ext_points, value)
    ##
    ## choose the nearest point; will always be either the
    ## index found by bisection, or the next-lower index
    if abs(ext_points[index]-value) >= abs(ext_points[index-1]-value):
        index -= 1
    ##
    ## map index to [0, npoints)
    index %= len(points)
    ##
    ## done
    return points[index]

如所写,除非输入像没有点一样不稳定,或者绑定(bind)==0,否则工作。

关于python - 在循环有序列表中找到最接近值的优雅方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16622836/

相关文章:

python - 如何从 gensim 0.11.1 中的 Doc2Vec 获取文档向量?

python - 如何使用 selenium 和 python 在 phantomjs 中设置 cookie?

python - Boto 请求过期

python - Django 错误 : NoReverseMatch

python - 使用 Python 从 URL 下载 .mp4 的子剪辑

python - 使用 Pandas 对 float 列进行分组

python - 此代码中的控制流是什么?

python - 在python中乘以除一行/列之外的整个矩阵

python - 我一直在编辑 json 文件,但文件本身没有更新(python)

python - 在Python中对一系列数据进行分类的最佳方法