如何有效地检查python中的连续范围

pyl*_*ist 3 python range python-3.x

根据范围分配等级:

def getGrade(size):
    grade =''
    if size <= 32:
        grade = 'p4'
    elif size > 32 and size <=64:
        grade = 'p6'
    elif size > 64 and size <= 128:
        grade = 'p10'
    elif size > 128 and size <= 256:
        grade = 'p15'
    elif size > 256 and size <=512:
        grade = 'p20'
    elif size > 512 and size <= 1024:
        grade = 'p30'
    elif size > 1024 and size <= 2048:
        grade = 'p40'
    ......
Run Code Online (Sandbox Code Playgroud)

问题是需要再增加20个检查,所以有什么办法比这个方法更好.

ffe*_*rri 5

由于范围是连续的,您可以避免重复下限.

将所有范围放在元组中可以节省一些输入(如果第一个范围没有下降到负无穷大,请考虑(0, None)在所有其他范围之前添加元组:

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

    for maxVal, grade in grades:
        if size <= maxVal:
            return grade
Run Code Online (Sandbox Code Playgroud)

测试:

>>> getGrade(45)
'p6'
>>> getGrade(100)
'p10'
Run Code Online (Sandbox Code Playgroud)

效率:

如果grades列表非常长,则可以比扫描每个项目获得更好的运行时间.由于列表已排序,您可以bisect通过替换for循环来使用:

    for maxVal, grade in grades:
        if size <= maxVal:
            return grade
Run Code Online (Sandbox Code Playgroud)

有:

    index = bisect.bisect(grades, (size, ))
    if index < len(grades):
        return grades[index][1]
Run Code Online (Sandbox Code Playgroud)

步数由N(长度grades)减少(在最坏的情况下)到log 2(N).

  • @hiroprotagonist只有一行长,但它在令牌数量上更长.无论如何,代码长度的挑战在这里是愚蠢的; 关键是"详细"`for`更具可读性.(尽管我是oneliner的粉丝) (2认同)