寻找包含列表中所有角度的最小范围

7

我有一个排序过的值列表,表示角度(以度为单位),全部在[0,360)的范围内。

我的目标是找到适合列表中所有角度的最佳范围(最小范围)。

一些例子:

  • 给定列表angles = [0,1,2,10,20,35],答案将是(0,35)

  • 给定列表angles = [10,20,340,355],由于值的循环性质,答案将是(340,20)

我的当前脚本工作方式如下:

MAX_ANGLE = 360

def get_best_range(angles):

    number_of_angles = len(angles)

    # Append the list of angles with the same angles plus 360 (max value)
    angles = angles + [angle + MAX_ANGLE for angle in angles]

    # Create a list of all possible ranges
    possible_ranges = [(angles[i], angles[i+number_of_angles - 1]) for i in range(number_of_angles)]

    # Find the best range (minimum range)
    best_range = min(possible_ranges, key = lambda ang_range: ang_range[1] - ang_range[0])

    return best_range[0], best_range[1]%MAX_ANGLE

目前这是我最好的方法,它在O(n)时间内运行良好,但是我认为在Python中可能有更好的方法。也许有一些工具可以处理循环值?当我处理角度或其他循环值时总是感到有些麻烦。


1
你认为10和370是相同的角度还是不同的? - wim
同样的,我总是将角度表示在[0,360)范围内。 - DSLima90
2个回答

4
那个一行代码就可以解决问题:
max(zip(angles, angles[1:] + [360+angles[0]]), key = lambda x: x[1]-x[0])

(如果需要,您可以在之后将答案更改为小于360的值)


1
鉴于“angles”列表已排序 - Luchko
3
我有一个已经排好序的值列表。 - Ohad Eytan
1
这是一个很好的答案,它只是返回了范围的反向((35,360)(340,20)是我的例子),但我只需要将其反转(可以通过在一行代码中添加[::-1]来完成),并将其归一化到[0,360)范围内。这比我的解决方案好多了,谢谢! - DSLima90
这个答案如果能解释一下它是如何工作的话会更有帮助。 - Chuck Batson

0
 def f(my_list):

     maxi = max(my_list)
     mini = min(my_list)
     if maxi - mini < 180:
        return (mini, maxi)
     else:
       return (min([x for x in my_list if x >= 180]), max([x for x in my_list if x<180]))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接