6

问题:

编写一个 Python 函数,clip(lo, x, hi),如果 x 小于 lo,则返回 lo;如果 x 大于 hi,则为 hi;否则为 x。对于这个问题,你可以假设 lo < hi。

不要对这个问题使用任何条件语句。相反,使用内置的 Python 函数 min 和 max。在开始这个问题之前,您可能希望阅读有关 min 的文档和有关 max 的文档,并在您的解释器中尝试一下这些函数。

此函数接受三个数字并返回一个数字。

给出的代码:

def clip(lo, x, hi):
    '''
    Takes in three numbers and returns a value based on the value of x.
    Returns:
     - lo, when x < lo
     - hi, when x > hi
     - x, otherwise
    '''

我的代码添加:

def clip(lo, x, hi):
    '''
    Takes in three numbers and returns a value based on the value of x.
    Returns:
     - lo, when x < lo
     - hi, when x > hi
     - x, otherwise
    '''
    if min(x, lo, hi) == x:
        return lo
    elif max(x, lo, hi) == x:
        return hi
    else:
        return x

问题是:我不能使用任何条件。帮助!

4

10 回答 10

9

这是一个解决方案,假设 lo < hi。

def clip(lo, x, hi):
    return max(lo, min(hi, x))

在每种情况下它是如何工作的:

  • lo,当 x < lo如果 lo < hi,则 x < hi,所以min(hi, x)返回xmax(lo, x)返回lo
  • hi, 当 x > hi :min(hi, x)返回hi并且如果 lo < hi ,max(lo, hi)返回hi
  • x,否则:x > lo 和 x < hi,所以min(hi, x)返回xmax(lo, x)返回x
于 2013-02-16T20:02:48.630 回答
8

因此,到目前为止,您已经提出了许多选项。尚未发布的是嵌套的三元表达式:

def clip(lo, x, hi):
    return lo if x <= lo else hi if x >= hi else x

但由于这使用显式条件测试,可能不适合作为原始问题的解决方案。尽管如此,考虑到这些选项,这实际上具有短路 if 的优点x <= lo(所有其他方法评估所有比较和/或执行一两个方法调用)。让我们看看这些替代方案如何使用 timeit 实际执行(使用 Python 3.3 测试,因此 range 不会构建列表,而是返回一个迭代器):

python -m timeit -s "lo,hi=10,90" "[max(lo,min(hi,x)) for x in range(100)]"
10000 loops, best of 3: 54.5 usec per loop

(每次评估 2 个函数调用,会影响性能)

python -m timeit -s "lo,hi=10,90" "[(lo,(hi,x)[x<hi])[x>lo] for x in range(100)]"
10000 loops, best of 3: 40.9 usec per loop

(评估测试并为每次评估构建元组,但至少没有函数调用)

python -m timeit -s "lo,hi=10,90" "[sorted((lo,x,hi))[1] for x in range(100)]"
10000 loops, best of 3: 90.5 usec per loop

(构建元组和排序 - 抱歉,Gnibbler,这是最慢的)

python -m timeit -s "lo,hi=10,90" "[lo if x <= lo else hi if x >= hi else x for x in range(100)]"
100000 loops, best of 3: 18.9 usec per loop

(最快,没有函数调用,只评估x >= hiif x > lo

如果在测试范围内将 lo 的值移动到更高的位置,则可以看到这种短路:

python -m timeit -s "lo,hi=80,90" "[lo if x <= lo else hi if x >= hi else x for x in range(100)]"
100000 loops, best of 3: 15.1 usec per loop

(如果您想在 Python 2.x 下重现这些内容,请替换rangexrange。)

于 2013-02-17T02:39:55.067 回答
3

在不给出整个解决方案的情况下——你不需要“检查”任何东西。从底部开始限制的值lo是您从运行中获得的值max(x, lo)

此外,剪裁到一个边界的值不会受到剪裁到另一边界的影响,因此您可以安全地通过另一个校正运行一个校正的结果。

于 2013-02-16T19:48:58.290 回答
2

我浏览了所有案例,每个案例的答案都是按大小排列时的中间项

        def clip(lo,x,hi):
             t = hi + lo + x - max(lo,x,hi)- min(lo,x,hi)
             return t
于 2021-06-03T14:09:50.133 回答
1

另一种解决方案:

def clip(lo, x, hi):
    result = {x: x}
    result[min(x, lo)] = lo
    result[max(x, hi)] = hi
    return result[x]
于 2013-02-16T20:16:30.393 回答
1

解决方案:

def clip(lo, x, hi):
    x = max(lo, x)
    x = min(x, hi)   
    return x
于 2015-06-23T12:26:01.920 回答
0
def clip(lo, x, hi):
    return sorted((lo, x, hi))[1]
于 2013-02-16T20:10:03.520 回答
0

分钟?最大限度?关于什么:

def clip(lo,x,hi):
    return (lo,(hi,x)[x<hi])[x>lo]
于 2013-02-17T02:25:56.607 回答
0

这将在没有条件运算符的情况下解决问题。

max(lo,min(hi,x))
于 2015-07-08T21:55:53.913 回答
-2

这里也是一个解决方案:return min(max(x, lo), hi)

于 2015-01-19T18:21:57.863 回答