代码之家  ›  专栏  ›  技术社区  ›  Denilson Sá Maia

如何将整数钳制到某个范围?

  •  77
  • Denilson Sá Maia  · 技术社区  · 15 年前

    我有以下代码:

    new_index = index + offset
    if new_index < 0:
        new_index = 0
    if new_index >= len(mylist):
        new_index = len(mylist) - 1
    return mylist[new_index]
    

    基本上,我计算一个新的索引并用它从列表中找到一些元素。为了确保索引在列表的范围内,我需要编写这两个 if 语句分为4行。太冗长了,有点难看。。。我敢说,这是相当 .

    还有其他更简单、更紧凑的解决方案吗? (以及更多 蟒蛇

    是的,我知道我可以用 if else 一行,但不可读:

    new_index = 0 if new_index < 0 else len(mylist) - 1 if new_index >= len(mylist) else new_index
    

    我也知道我可以锁链 max() min() 一起。它更紧凑,但我觉得它有点晦涩,如果我打错了,更难找到错误。换句话说,我觉得这不是很直接。

    new_index = max(0, min(new_index, len(mylist)-1))
    
    9 回复  |  直到 7 年前
        1
  •  109
  •   S.Lott    15 年前

    事实上,这很清楚。很多人学得很快。你可以用评论来帮助他们。

    new_index = max(0, min(new_index, len(mylist)-1))
    
        2
  •  79
  •   John La Rooy    15 年前
    sorted((minval, value, maxval))[1]
    

    例如:

    >>> minval=3
    >>> maxval=7
    >>> for value in range(10):
    ...   print sorted((minval, value, maxval))[1]
    ... 
    3
    3
    3
    3
    4
    5
    6
    7
    7
    7
    
        3
  •  37
  •   Neil G    15 年前

    numpy.clip :

    index = numpy.clip(index, 0, len(my_list) - 1)
    
        4
  •  35
  •   Gringo Suave    7 年前

    import numpy
    np_clip = numpy.clip
    mm_clip = lambda x, l, u: max(l, min(u, x))
    s_clip = lambda x, l, u: sorted((x, l, u))[1]
    py_clip = lambda x, l, u: l if x < l else u if x > u else x
    
    >>> import random
    >>> rrange = random.randrange
    >>> %timeit mm_clip(rrange(100), 10, 90)
    1000000 loops, best of 3: 1.02 µs per loop
    
    >>> %timeit s_clip(rrange(100), 10, 90)
    1000000 loops, best of 3: 1.21 µs per loop
    
    >>> %timeit np_clip(rrange(100), 10, 90)
    100000 loops, best of 3: 6.12 µs per loop
    
    >>> %timeit py_clip(rrange(100), 10, 90)
    1000000 loops, best of 3: 783 ns per loop
    

    paxdiablo 成功了!,使用普通的ol python。纽比版本也许并不奇怪,是最慢的版本。可能是因为它在寻找数组,而其他版本只是对它们的参数进行排序。

        5
  •  14
  •   Laurence Gonsalves    15 年前

    链式 max() min() “在一起”是我见过的一个普通的成语。如果您发现很难读取,请编写一个helper函数来封装该操作:

    def clamp(minimum, x, maximum):
        return max(minimum, min(x, maximum))
    
        6
  •  13
  •   Gringo Suave    7 年前

    我喜爱的可读Python语言怎么了?:-)

    def addInRange(val, add, minval, maxval):
        newval = val + add
        if newval < minval: return minval
        if newval > maxval: return maxval
        return newval
    

    那就叫它像:

    val = addInRange(val, 7, 0, 42)
    

    或者一个更简单,更灵活的解决方案,你自己计算:

    def restrict(val, minval, maxval):
        if val < minval: return minval
        if val > maxval: return maxval
        return val
    
    x = restrict(x+10, 0, 42)
    

    如果你愿意,你甚至可以把最小/最大值列为一个列表,这样它看起来更“纯数学”:

    x = restrict(val+7, [0, 42])
    
        7
  •  8
  •   Jens Kirk Roybal    10 年前

    >>> def clip(val, min_, max_):
    ...     return min_ if val < min_ else max_ if val > max_ else val
    

    一些测试:

    >>> clip(5, 2, 7)
    5
    >>> clip(1, 2, 7)
    2
    >>> clip(8, 2, 7)
    7
    
        8
  •  6
  •   Greg Hewgill    15 年前

    如果您的代码看起来太难处理,一个函数可能会有帮助:

    def clamp(minvalue, value, maxvalue):
        return max(minvalue, min(value, maxvalue))
    
    new_index = clamp(0, new_index, len(mylist)-1)
    
        9
  •  2
  •   Jetze Schaafsma    14 年前

    避免为这样的小任务编写函数,除非经常应用它们,否则会使代码变得混乱。

    对于个人价值观:

    min(clamp_max, max(clamp_min, value))
    

    map(lambda x: min(clamp_max, max(clamp_min, x)), values)