Return 0.0 和 1.0 如果输入低于 0.0 或高于 1.0

Return 0.0 and 1.0 if input falls below 0.0 or above 1.0

目标是 "do something" 如果输入值介于 (0.0, 1.0) 之间。

否则,

最直接的方法是:

def func(x):
    if x >= 1.0:
        return 1.0
    elif x <= 0.0:
        return 0.0
    else: 
        return do_something(x)

但最好使用一些 max/min 技巧,例如:

def func(x):
    if 0 < x < 1.0:
        return do_something(x)
    else:
        return max(min(x, 1.0), 0.0)

如果值低于 0 和高于 1,哪种编码风格更 Pythonic return 裁剪值,否则,需要操纵浮点数?

do_something() 是一些浮动操作,应该 return 一个介于 (0.0, 1.0) 之间的值,即不包括 0.0 和 1.0。

为简单起见,将其视为:

def do_something(x):
    return x**2

为了进一步说明问题,(0.0, 1.0)范围不包括0.0和1.0,即

>>> x = 0.231
>>> 0 < x < 1.0
True

因此,如果 0 < x < 1.0,所需的输出必须通过 do_something() 函数,该函数 return 是一个值 (0.0, 1.0),例如

>>> x**2
0.053361000000000006
>>> 0 < x**2 < 1.0
True

我想当你问我为什么不先 do_something() 然后 "clamp"/"clip" 输出时,评论中的混乱就来了,即:

>>> x = 0.231
>>> max(min(x**2, 1.0), 0.0)
0.053361000000000006

但是假设您的否定否定。作为输入:

>>> x = -0.231

期望的输出是 0.0。但是如果我们只是简单地先 do_something() 然后 "clamp"/"clip",我们会得到错误的输出:

>>> x = - 0.231
>>> max(min(x**2, 1.0), 0.0)
0.053361000000000006

也许正方形描述起来有点过于简单 do_something()

实际函数看起来更像这样:

def do_something(x):
    ratio_y, score_y = 1.5, 0.5
    beta = math.log(score_y) / math.log(score_y)**2
    return math.exp(beta * math.log(x)**2)'

由于对数的渐近线性质,在调用 do_something() 函数之前需要明确检查 (0.0, 1.0)。

如果你喜欢,你可以使用装饰器风格。

装饰器(自定义最小值和最大值):

def limit_decorator(min_val, max_val):
    def inner_decorator(func):
        def wrapping_func(x):
            if x >= max_val:
                return max_val
            elif x <= min_val:
                return min_val
            else:
                return func(x)
        return wrapping_func
    return inner_decorator

你可以这样使用它:

@limit_decorator(0.0, 1.0)
def do_something(value):
    return value**2

或者,您可以使用一个简单的装饰器(具有预定义的限制):

def limit_decorator(func):
    def wrapping_func(x):
        if x >= 1.0:
            return 1.0
        elif x <= 0.0:
            return 0.0
        else:
            return func(x)
    return wrapping_func

你喜欢哪个:

@limit_decorator
def do_something(value):
    return value**2