python - How to apply max & min boundaries to a value without using conditional statements -
problem:
write python function, clip(lo, x, hi) returns lo if x less lo; hi if x greater hi; , x otherwise. problem, can assume lo < hi.
don't utilize conditional statements problem. instead, utilize built in python functions min , max. may wish read documentation on min , documentation on max, , play around these functions bit in interpreter, before origin problem.
this function takes in 3 numbers , returns single number.
code given:
def clip(lo, x, hi): ''' takes in 3 numbers , returns value based on value of x. returns: - lo, when x < lo - hi, when x > hi - x, otherwise '''
my code added:
def clip(lo, x, hi): ''' takes in 3 numbers , returns value based on value of x. returns: - lo, when x < lo - hi, when x > hi - x, otherwise ''' if min(x, lo, hi) == x: homecoming lo elif max(x, lo, hi) == x: homecoming hi else: homecoming x
here's problem: can't utilize any conditionals. help!
so have number of options proposed far. not yet posted nested ternary expression:
def clip(lo, x, hi): homecoming lo if x <= lo else hi if x >= hi else x
but since uses explicit conditional tests, not suitable solution original question. still, given these options, 1 has advantages of short-circuiting if x <= lo
(all other methods evaluate comparisons and/or perform 1 or 2 method calls). let's see how these alternatives perform using timeit (tested python 3.3, range not build list, returns iterator):
python -m timeit -s "lo,hi=10,90" "[max(lo,min(hi,x)) x in range(100)]" 10000 loops, best of 3: 54.5 usec per loop
(2 function calls per evaluation, kills performance)
python -m timeit -s "lo,hi=10,90" "[(lo,(hi,x)[x<hi])[x>lo] x in range(100)]" 10000 loops, best of 3: 40.9 usec per loop
(evaluates both tests , builds tuples every evaluation, @ to the lowest degree no function calls)
python -m timeit -s "lo,hi=10,90" "[sorted((lo,x,hi))[1] x in range(100)]" 10000 loops, best of 3: 90.5 usec per loop
(builds tuple , sorts - sorry, gnibbler, slowest)
python -m timeit -s "lo,hi=10,90" "[lo if x <= lo else hi if x >= hi else x x in range(100)]" 100000 loops, best of 3: 18.9 usec per loop
(fastest, no function calls, evaluates x >= hi
if x > lo
)
this short-circuiting can seen if move value of lo much higher in test range:
python -m timeit -s "lo,hi=80,90" "[lo if x <= lo else hi if x >= hi else x x in range(100)]" 100000 loops, best of 3: 15.1 usec per loop
(if want reproduce these under python 2.x, replace range
xrange
.)
python
No comments:
Post a Comment