如何在不使用条件语句的情况下将max和min边界应用于值

时间:2022-09-26 21:17:15

Problem:

Write a Python function, clip(lo, x, hi) that returns lo if x is less than lo; hi if x is greater than hi; and x otherwise. For this problem, you can assume that lo < hi.

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

Don't use any conditional statements for this problem. Instead, use the built in Python functions min and max. You may wish to read the documentation on min and the documentation on max, and play around with these functions a bit in your interpreter, before beginning this problem.

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

This function takes in three numbers and returns a single number.

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

Code Given:

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
    '''

My Code Added:

我的代码已添加:

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

Here's the problem: I can't use ANY conditionals. Help!

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

9 个解决方案

#1


8  

So you have a number of options proposed so far. Not yet posted is the nested ternary expression:

所以到目前为止你有很多选择。尚未发布的是嵌套的三元表达式:

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

But since this uses explicit conditional tests, probably not suitable as a solution to the original question. Still, given these options, this is the one that actually has the advantages of short-circuiting if x <= lo (all other methods evaluate all comparisons and/or perform one or two method calls). Let's see how these alternatives actually perform using timeit (tested with Python 3.3, so range does not build a list, but returns an iterator):

但由于这使用了明确的条件测试,可能不适合作为原始问题的解决方案。仍然,给定这些选项,如果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 function calls per evaluation, kills performance)

(每次评估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

(evaluates both tests and builds tuples for every evaluation, but at least no function calls)

(评估每个评估的测试和构建元组,但至少没有函数调用)

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

(builds tuple and sorts - sorry, Gnibbler, this is the slowest)

(建立元组和排序 - 对不起,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

(fastest, no function calls, only evaluates x >= hi if x > lo)

(最快,没有函数调用,只评估x> = hi,如果x> lo)

This short-circuiting can be seen if you move the value of lo to much higher in the test range:

如果在测试范围内将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

(If you want to reproduce these under Python 2.x, replace range with xrange.)

(如果要在Python 2.x下重现这些,请用xrange替换范围。)

#2


8  

Here is a solution, assuming that lo < hi.

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

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

How it works in each case:

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

  • lo, when x < lo: if lo < hi, then x < hi, so min(hi, x) returns x and max(lo, x) returns lo.
  • lo,当x

  • hi, when x > hi: min(hi, x) returns hi and if lo < hi, max(lo, hi) returns hi
  • 嗨,当x> hi:min(hi,x)返回hi并且如果lo ,则max(lo,hi)返回hi

  • x, otherwise: x > lo and x < hi, so min(hi, x) returns x and max(lo, x) returns x
  • x,否则:x> lo和x ,所以min(hi,x)返回x,max(lo,x)返回x

#3


3  

Without giving out the whole solution - you don't need to "check" anything. A value limited to lo from the bottom is what you get from running max(x, lo).

没有给出整个解决方案 - 你不需要“检查”任何东西。从底部限制为lo的值是运行max(x,lo)得到的值。

Also value clipped to one boundary is not going to be affected by clipping to the other boundary, so you can safely run the result of one correction through another one.

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

#4


1  

Another solution:

def clip(lo, x, hi):
    result = {x: x}
    result[min(x, lo)] = lo
    result[max(x, hi)] = hi
    return result[x]

#5


1  

solution:

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

#6


0  

def clip(lo, x, hi):
    return sorted((lo, x, hi))[1]

#7


0  

min? max? What about:

分?最大?关于什么:

def clip(lo,x,hi):
    return (lo,(hi,x)[x<hi])[x>lo]

#8


0  

This will do the trick without conditional operators.

这将在没有条件运算符的情况下完成。

max(lo,min(hi,x))

#9


-2  

here is also a solution: return min(max(x, lo), hi)

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

#1


8  

So you have a number of options proposed so far. Not yet posted is the nested ternary expression:

所以到目前为止你有很多选择。尚未发布的是嵌套的三元表达式:

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

But since this uses explicit conditional tests, probably not suitable as a solution to the original question. Still, given these options, this is the one that actually has the advantages of short-circuiting if x <= lo (all other methods evaluate all comparisons and/or perform one or two method calls). Let's see how these alternatives actually perform using timeit (tested with Python 3.3, so range does not build a list, but returns an iterator):

但由于这使用了明确的条件测试,可能不适合作为原始问题的解决方案。仍然,给定这些选项,如果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 function calls per evaluation, kills performance)

(每次评估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

(evaluates both tests and builds tuples for every evaluation, but at least no function calls)

(评估每个评估的测试和构建元组,但至少没有函数调用)

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

(builds tuple and sorts - sorry, Gnibbler, this is the slowest)

(建立元组和排序 - 对不起,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

(fastest, no function calls, only evaluates x >= hi if x > lo)

(最快,没有函数调用,只评估x> = hi,如果x> lo)

This short-circuiting can be seen if you move the value of lo to much higher in the test range:

如果在测试范围内将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

(If you want to reproduce these under Python 2.x, replace range with xrange.)

(如果要在Python 2.x下重现这些,请用xrange替换范围。)

#2


8  

Here is a solution, assuming that lo < hi.

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

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

How it works in each case:

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

  • lo, when x < lo: if lo < hi, then x < hi, so min(hi, x) returns x and max(lo, x) returns lo.
  • lo,当x

  • hi, when x > hi: min(hi, x) returns hi and if lo < hi, max(lo, hi) returns hi
  • 嗨,当x> hi:min(hi,x)返回hi并且如果lo ,则max(lo,hi)返回hi

  • x, otherwise: x > lo and x < hi, so min(hi, x) returns x and max(lo, x) returns x
  • x,否则:x> lo和x ,所以min(hi,x)返回x,max(lo,x)返回x

#3


3  

Without giving out the whole solution - you don't need to "check" anything. A value limited to lo from the bottom is what you get from running max(x, lo).

没有给出整个解决方案 - 你不需要“检查”任何东西。从底部限制为lo的值是运行max(x,lo)得到的值。

Also value clipped to one boundary is not going to be affected by clipping to the other boundary, so you can safely run the result of one correction through another one.

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

#4


1  

Another solution:

def clip(lo, x, hi):
    result = {x: x}
    result[min(x, lo)] = lo
    result[max(x, hi)] = hi
    return result[x]

#5


1  

solution:

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

#6


0  

def clip(lo, x, hi):
    return sorted((lo, x, hi))[1]

#7


0  

min? max? What about:

分?最大?关于什么:

def clip(lo,x,hi):
    return (lo,(hi,x)[x<hi])[x>lo]

#8


0  

This will do the trick without conditional operators.

这将在没有条件运算符的情况下完成。

max(lo,min(hi,x))

#9


-2  

here is also a solution: return min(max(x, lo), hi)

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