优化的方式来查找数字所在的范围

时间:2018-05-14 07:29:11

标签: python

我有多个范围可以说1-1000,1000-2000,2000-3000,3000-4000,4000-5000。我从用户那里得到一个号码,现在我需要找到它所在的范围。一种方法是创建多个if语句并从那里检查如下:

if num>=1 and num < 1000:
    print "1"
elif num >=1000 and num < 2000:
    print "2"
....   

这种方法会创建很多分支。

在没有这么多分支且复杂性最低的情况下,是否有一种优化的方法可以做到这一点?

PS:我只是在python中编写代码,因为它的编写时间较短,但在任何语言中都可以这样。范围和输出也可能非常不同。 范围和输出是示例,可以是1-100,100-1000,1000-1500等任何类型,输出类似“非常低,低,中等”。

6 个答案:

答案 0 :(得分:1)

将范围的起点或终点存储在列表中,并将其与数字一起排序以查找其确切范围。

import numpy as np
start = [1,1000,2000,3000,4000]
print(list(np.sort(start+[num])).index(num))

答案 1 :(得分:0)

可能只是除以1000并占据整个部分:

这里是python的例子:

>>> x=3608
>>> int(x/1000+1)
4

在您的帖子中发表评论/编辑后,如果您需要不同的输出(例如字符串),您可以(在python中)使用dict

>>> Output={'1': 'very low', '2': 'low', '3': 'medium','4':'high' }
>>> x=2954
>>> Output[str(int(x/1000+1))]
'medium'

答案 2 :(得分:0)

my_range=(1,1000), (1000,2000), (2000,3000), (3000,4000), (4000,5000)
my_output='Very Low, Low, Medium, High, Very High'.split(', ')
num=3565
for k,i in enumerate(my_range):
   if i[0]<=num<i[1]:print(my_output[k]);break
else:
   print('Out of range')

答案 3 :(得分:0)

如果您的范围没有遵循任何特定的逻辑,除了逐个测试之外,您无能为力,但您仍然可以通过使用循环来简化代码:

ranges = [[0,1000],[1500,1600],[1200,1220]]

def find_range(num, ranges)
    for low, high in ranges:
        if low <= num < high:
            return low, high # or any other formating using a dict for example

当然,您可以通过对范围进行排序然后进行二分搜索而不是线性来优化一点......

答案 4 :(得分:0)

怀疑您有许多中断并需要优化搜索,您可以在有序的断点列表上进行二分法,从而导致对数时间消耗:

import random
import time


def split_pivot(intervals, number):
    """Divide and conquer recursively."""
    if len(intervals) == 1:
        return intervals[0]
    if len(intervals) == 2:
        if number >= intervals[1][1][0]:
            return intervals[1]
        elif number < intervals[0][1][1]:
            return intervals[0]
        else:
            raise

    pivot = int(len(intervals) // 2.0)

    if number < intervals[pivot][1][1]:
        return split_pivot(intervals[:pivot + 1], number)
    elif number >= intervals[pivot + 1][1][0]:
        return split_pivot(intervals[pivot + 1:], number)
    else:
        raise


if __name__ == '__main__':
    UPPER_BOUND = 10000000

    newbreak = 0
    manybreaks = []
    while newbreak < UPPER_BOUND:
        step = int(random.random() * 10) + 1
        manybreaks.append(newbreak + step)
        newbreak = manybreaks[-1]
    print('Breaks: {:d}'.format(len(manybreaks)))

    intervals = [
        (idx, (manybreaks[idx], manybreaks[idx + 1]))
        for idx in range(len(manybreaks) - 1)
    ]
    print('Intervals: {:d}'.format(len(intervals)))
    print(
        '  Example: idx {tpl[0]:d}, lower {tpl[1][0]:d}, upper {tpl[1][1]:d}'
        .format(tpl=random.choice(intervals)))

    thenumber = int(random.random() * UPPER_BOUND)
    print('Number: {:d}'.format(thenumber))

    t0 = time.time()
    result = split_pivot(intervals, thenumber)
    t1 = time.time()

    print('Result: {e[0]:d} ({e[1][0]:d}, {e[1][1]:d})'.format(e=result))
    print('  Done in {:.4f}s'.format(t1 - t0))

搜索结果本身(在我的机器上)低于0.05秒。断点和相应间隔的生成大约持续4.5秒:

Breaks: 1818199
Intervals: 1818198
  Example: idx 605849, lower 3330441, upper 3330446
Number: 6951844
Result: 1263944 (6951843, 6951847)
  Done in 0.0436s

答案 5 :(得分:0)

这样的事情怎么样:

ranges = {
    0: 'undefined range',
    1000: '1',
    1500: '2',
    2500: '3'
}

num = 500

print(ranges[max(ranges, key=lambda x: num < x)])

输出:1