从一个角度产生方向的简单,丑陋的功能。

时间:2016-08-16 19:05:52

标签: python

我写了一个函数,它取一个学位并返回方向为' N' NE' NE'等等。非常简单,但它很难看 - 是否有任何方法可以重写它以使它更漂亮?

def orientation(tn):
    if 23 <= tn <= 67:
        o = 'NE'
    elif 68 <= tn <= 113:
        o = 'E'    
    elif 114 <= tn <= 158:
        o = 'SE'
    elif 159 <= tn <= 203:
        o = 'S'
    elif 204 <= tn <= 248:
        o = 'SW'
    elif 249 <= tn <= 293:
        o = 'W'
    elif 294 <= tn <= 338:
        o = 'NW'
    else:
        o = 'N'
    return o

4 个答案:

答案 0 :(得分:18)

使用bisection

from bisect import bisect_left

directions = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'N']
boundaries = [22,  67,   113, 158,  203, 248,  293, 338,  360]

def orientation(tn):
    return directions[bisect_left(boundaries, tn)]

bisect_left()(非常有效)找到您将tn插入boundaries列表的索引;然后将该索引映射到directions列表以转换为字符串。

Bisection最多只需4个步骤即可找到正确的边界(log2(len(boundaries)))。

您还可以添加22并将模数值除以模数360:

directions = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'N']

def orientation(tn):
    index = ((tn + 22) % 360) // 45
    return directions[index]

然而,您的原始边界不是均匀分布在每个45度,因此结果略有不同(您的N边界跨度为44度,而E分配为46度)。 Bisection并不关心这些例外情况;你可以随心所欲地改变边界。

答案 1 :(得分:6)

您可以将整数索引计算到指南针方向列表中:

def compass(angle):
    return ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'N'][int(8*(angle+22.)/360)]

答案 2 :(得分:4)

尝试将整数除以45并按此数字(索引)寻址数组成员。该数组应包含方向。

答案 3 :(得分:1)

相同的原则,但更清晰的imo,改为使用ternary operator

def orientation(tn):
  tn = mod(tn, 360)
  return "N"  if tn < 23  else \
         "NE" if tn < 68  else \
         "E"  if tn < 114 else \
         "SE" if tn < 159 else \
         "S"  if tn < 204 else \
         "SW" if tn < 249 else \
         "W"  if tn < 294 else \
         "NW" if tn < 339 else \
         "N"

显然,这种方法并不适用于其他场景,但就个人而言,对于您的特定问题,我实际上更喜欢这个而不是更通用的替代方案,因为它是简单,清晰,可读,简单的代码:任何登陆此定义的人都会知道无论编程技巧如何,它都会在眨眼之间完成它的作用。 :P