How to limit a number to be within a specified range? (Python)

PythonMaxMin

Python Problem Overview


I want to limit a number to be within a certain range. Currently, I am doing the following:

minN = 1
maxN = 10
n = something() #some return value from a function
n = max(minN, n)
n = min(maxN, n)

This keeps it within minN and maxN, but it doesn't look very nice. How could I do it better?

PS: FYI, I am using Python 2.6.

Python Solutions


Solution 1 - Python

def clamp(n, minn, maxn):
    return max(min(maxn, n), minn)

or functionally equivalent:

clamp = lambda n, minn, maxn: max(min(maxn, n), minn)

now, you use:

n = clamp(n, 7, 42)

or make it perfectly clear:

n = minn if n < minn else maxn if n > maxn else n

even clearer:

def clamp(n, minn, maxn):
    if n < minn:
        return minn
    elif n > maxn:
        return maxn
    else:
        return n

Solution 2 - Python

Simply use numpy.clip() (doc):

n = np.clip(n, minN, maxN)

It also works for whole arrays:

my_array = np.clip(my_array, minN, maxN)

Solution 3 - Python

If you want to be cute, you can do:

n = sorted([minN, n, maxN])[1]

Solution 4 - Python

Define a class and have a method for setting the value which performs those validations.

Something vaguely like the below:

class BoundedNumber(object):
    def __init__(self, value, min_=1, max_=10):
        self.min_ = min_
        self.max_ = max_
        self.set(value)

    def set(self, newValue):
        self.n = max(self.min_, min(self.max_, newValue))

# usage

bounded = BoundedNumber(something())
bounded.set(someOtherThing())

bounded2 = BoundedNumber(someValue(), min_=8, max_=10)
bounded2.set(5)    # bounded2.n = 8

Solution 5 - Python

Could you not string together some one-line python conditional statements?

I came across this question when looking for a way to limit pixel values between 0 and 255, and didn't think that using max() and min() was very readable so wrote the following function:

def clamp(x, minn, maxx):
   return x if x > minm and x < maxx else (minn if x < minn else maxx)

I would be interested to see how someone more experienced than me would find this way of clamping a value. I assume it must be less efficient than using min() and max(), but it may be useful for someone looking for a more readable (to me at least) function.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMantis TobogganView Question on Stackoverflow
Solution 1 - PythonAdrien PlissonView Answer on Stackoverflow
Solution 2 - PythonBjörnView Answer on Stackoverflow
Solution 3 - PythonSteve HowardView Answer on Stackoverflow
Solution 4 - PythonPlatinum AzureView Answer on Stackoverflow
Solution 5 - PythonJoe IddonView Answer on Stackoverflow