Python:舍入到列表中的下一个预定义整数

时间:2012-03-26 08:48:35

标签: python

我有一个预定义整数的Python列表:

intvals = [5000, 7500, 10000, 20000, 30000, 40000, 50000]

我需要向下舍入到列表中的下一个更高/更高的值。例如,给定数字8000,结果应为[7500, 10000]。对于42000,它应为[40000, 50000]。我想知道是否有一种简单的方法可以做到。

我的想法是创建一个具有两个循环的函数 - 一个减少值-1直到它在列表中找到一个循环,另一个将值增加1直到找到更高的匹配。这可行,但也许有更好的解决方案?

5 个答案:

答案 0 :(得分:16)

这对bisect.bisect_right()和bisect.bisect_left()来说是完美的。

以下是一些可以展开的示例代码:

import bisect

def get_interval(x):
    intvals = [5000, 7500, 10000, 20000, 30000, 40000, 50000]
    i = bisect.bisect_right(intvals,x)
    return intvals[i-1:i+1]

print get_interval(5500)

"""
>>>
[5000, 7500]
"""

这种技术很快,因为它使用二进制搜索(所以logN而不是N次查找)

答案 1 :(得分:6)

您可以使用bisect模块。您可能需要调整示例以满足您的边界案例需求。

>>> import bisect
>>> def RoundUpDown(rangeList,num):
    beg = bisect.bisect_right(rangeList,num)
    if rangeList[beg-1] == num: #Handle Perfect Hit Edge Case
        return [num,num]
    elif not beg: #Left Edge Case
        return [None,rangeList[0]]
    elif beg == len(rangeList): #Right Edge Case
        return [rangeList[-1],None]
    else:
        return rangeList[beg-1:beg+1]


>>> RoundUpDown([5000, 7500, 10000, 20000, 30000, 40000, 50000],41000)
[40000, 50000]
>>> RoundUpDown([5000, 7500, 10000, 20000, 30000, 40000, 50000],5000)
[5000, 5000]
>>> RoundUpDown([5000, 7500, 10000, 20000, 30000, 40000, 50000],500)
[None, 5000]
>>> RoundUpDown([5000, 7500, 10000, 20000, 30000, 40000, 50000],50000)
[50000, 50000]
>>> RoundUpDown([5000, 7500, 10000, 20000, 30000, 40000, 50000],51000)
[50000, None]
>>> RoundUpDown([5000, 7500, 10000, 20000, 30000, 40000, 50000],7500)
[7500, 7500]
>>> 

答案 2 :(得分:3)

bisect专为此类搜索而打造。

>>> intvals[bisect.bisect(intvals, 8000)]
10000
>>> intvals[bisect.bisect(intvals, 42000)]
50000

答案 3 :(得分:0)

将'minDiff'int设置为maxint,将'minIndex'设置为-1。迭代列表并计算索引列表值与目标之间差异的绝对值。如果此值小于minDiff,则将其加载到minDiff并将索引存储在minIndex中。如果该值大于minDiff,则返回minIndex。注 - 假定列表已排序。如果未对列表进行排序,则必须迭代整个列表以确保找到最小差异。

答案 4 :(得分:0)

如果您的间隔不是太大而且您不太担心内存消耗,那么以下解决方案将会很快:

intvals = [5000, 7500, 10000, 20000, 30000, 40000, 50000]

pairs = zip(intvals,intvals[1:])
d = {}
for start,end in pairs:
    for i in range(start,end+1):
        d[i] = (start,end)

def get_interval(i):
    if i in d:
        return d[i]
    else:
        return -1

print get_interval(5500)

"""
>>>
(5000, 7500)
"""

注意我并不担心get_interval(7500)应该返回什么(虽然7500是两个间隔..)但你可以纠正它是你想要的。