how to efficiently check contiguous ranges in python

夙愿已清 提交于 2019-12-05 18:22:07

Due do the ranges being contiguous, you can avoid repeating the lower bound.

Putting all the ranges in tuples can save you some typing (if the first range does not go down to negative infinity, consider adding the tuple (0, None) before all others:

def getGrade(size):
    grades = (
         (32, 'p4'),
         (64, 'p6'),
        (128, 'p10'),
        ...
    )

    for maxVal, grade in grades:
        if size <= maxVal:
            return grade

Test:

>>> getGrade(45)
'p6'
>>> getGrade(100)
'p10'

Efficiency:

If the grades list is really long, you can achieve better runtime than scanning every item. Since the list is sorted, you can use bisect, by replacing the for loop:

    for maxVal, grade in grades:
        if size <= maxVal:
            return grade

with:

    index = bisect.bisect(grades, (size, ))
    if index < len(grades):
        return grades[index][1]

The number of steps is reduced (in the worst case) from N (the length of grades) to log2(N).

A brute force approach would be simple as

all_grades = [i for i in chain(repeat('p4',32),repeat('p6',64-32) and so on)]

then you can get grade as

grade = all_grades[size-1]

it may require space if list is exponential

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!