将整数范围映射到单个整数

时间:2014-06-21 12:56:18

标签: python django dictionary map

我有一个函数接收一个整数作为输入,并根据此输入所在的范围,为其分配一个难度值。我知道这可以使用if else循环来完成。我想知道是否有更有效/更清洁的方法来做到这一点。

我试图做这样的事情

TIME_RATING_KEY ={
    range(0,46):1,
    range(46,91):2,
    range(91,136):3,
    range(136,201):4,
    range(201,10800):5,
}

但是发现我们可以在dict中使用range作为键(对吗?)。那么有更好的方法吗?

2 个答案:

答案 0 :(得分:3)

您可以实施interval tree。这种数据结构能够返回与给定输入点相交的所有间隔。 在您的情况下,间隔不会重叠,因此它们总是会返回1个间隔。

居中间隔树在O(log n + m)时间内运行,其中m是返回的间隔数(在您的情况下为1)。因此,这会降低从O(n)O(log n)的复杂性。

这些间隔树的想法如下:

  • 您考虑包含所有区间的区间
  • 取该间隔的中心,将给定的间隔划分为在该点之前结束的间隔,包含该点的那些以及在该点之后开始的间隔。
  • 递归构建相同类型的树,用于在中心之前结束的间隔和在其之后开始的间隔
  • 将包含中心点的间隔保存在两个排序的序列中。一个按起点排序,另一个按结束点排序

根据中心点向左或向右搜索时。当您找到重叠时,您要对要检查的排序序列使用二进制搜索(这样不仅可以查找包含给定点的间隔,还可以查找相交或包含给定间隔的间隔)。

修改数据结构以返回特定值而不是找到的间隔是微不足道的。


这就是说,从上下文中我不认为你实际上需要降低这种查找的效率,你应该使用更简单,更易读的解决方案,因为它更易于维护,并且制作的机会更少错误。

然而,关于mroe高效数据结构的阅读在未来可能会变得有用。

答案 1 :(得分:2)

最简单的方法可能就是写一个简短的函数:

def convert(n, difficulties=[0, 46, 91, 136, 201]):
    if n < difficulties[0]:
        raise ValueError
    for difficulty, end in enumerate(difficulties):
        if n < end:
            return difficulty
    else:
        return len(difficulties)

示例:

>>> convert(32)
1
>>> convert(68)
2
>>> convert(150)
4
>>> convert(250)
5

作为旁注:你可以在Python 3.x中使用range作为字典键,但不能直接在2.x中使用(因为range返回一个列表)。你可以这样做:

TIME_RATING_KEY = {tuple(range(0, 46)): 1, ...}

然而,这不会有太大帮助!