检查数字在哪个范围内

时间:2018-08-01 19:58:56

标签: python range

我需要找到一个数字(在这种情况下为value)在哪个范围内。除此以外,我找不到其他方法来将i设置为所需的内容:

if value < -64:
  i = 0
elif value < -32:
  i = 1
elif value < -16:
  i = 2
elif value < -8:
  i = 3
elif value < -4:
  i = 4
elif value < -2:
  i = 5
elif value < -1:
  i = 6
elif value < -0.5:
  i = 7
elif value < 0:
  i = 8
elif value < 0.5:
  i = 9
elif value < 1:
  i = 10
elif value < 2:
  i = 11
elif value < 4:
  i = 12
elif value < 8:
  i = 13
elif value < 16:
  i = 14
elif value < 32:
  i = 15
elif value < 64:
  i = 16
else:
  i = 17

这是可怕的代码,我讨厌它。有什么办法可以做这样的事吗?

ranges = [-64, -32, -16 ... 32, 64]
i = find_which_range(value, ranges)

谢谢!

5 个答案:

答案 0 :(得分:2)

根据您描述的方式,您可以执行以下操作:

ranges = [-64, -32, -16, -8, -4, -2, -1, -0.5, 0, 0.5, 1, 2, 4, 8, 16, 32, 64]

def build_ranges(power):
    ranges = [-0.5, 0, 0.5]
    for i in range(power):
        ranges.append(2**i)
        ranges.append(-2**i)
    return sorted(ranges)

def find_which_range(value, ranges):
    for i, range in enumerate(sorted(ranges)):
        if value < range:
            return i
    return None

output = find_which_range(value, ranges)

答案 1 :(得分:2)

使用bisect

import bisect

ranges = [-64, -32, -16, -8, -4, -2, -1, -0.5, 0, 0.5, 1, 2, 4, 8, 16, 32, 64]

print(bisect.bisect(ranges, -65))
# 0

print(bisect.bisect(ranges, -64))
# 1

print(bisect.bisect(ranges, 63))
#16

print(bisect.bisect(ranges, 64))
# 17

bisect.bisect(l, value)返回必须在value中插入l的索引,以使左侧的所有值都小于value。由于使用了二等分算法,因此搜索大型列表也将很快。

答案 2 :(得分:1)

Mathew提供了一个运行良好的循环解决方案。但也请注意,您基本上正在检查,您的数字介于2的幂之间。因此,您可以获取日志。

import math
a_value = abs(value)
sign = 1 if value > 0 else -1
lg_value = math.log2(a_value)
range_ = (2**(sign*math.floor(lg_value)), 2**(sign*math.ceil(lg_value)))

请注意,对于范围<1,需要进行一些修改。

答案 3 :(得分:1)

人们已经提供了更短(更有效)的解决方案。我只是在这里发布我的尝试,只是为了展示使用列表理解来解决该问题的另一种方法和逻辑。

def find_which_range(value, ranges):
    if value <= min(ranges):
        c = 0
    elif value >= max(ranges): 
        c = len(ranges)
    else:
        c = [i+1 for i in range(len(ranges)-1) if ranges[i] <= value <= ranges[i+1]][0]
    return c

value = -9
i = find_which_range(value, ranges) 

答案 4 :(得分:0)

要找到正确的范围,可以使用zip函数在每个范围内进行迭代,如下所示:

ranges = [-64, -32, -16, -8, -4, -2, -1, -0.5, 0, 0.5, 1, 2, 4, 8, 16, 32, 64]

i = 9

for p, n in zip(ranges[:-1], ranges[1:]):
    if p <= i < n:
        r = p, n
        break
else:
    raise ValueError(i)

print(r)

您得到:(8,16)

然后,您可以在每个范围和目标值之间使用映射,如下所示:

mapping = {
  (-64, -32): 1,
  (-32, -16): 2,
  (-16, -8): 3
}

print(mapping[(-32, -16)])
2