Where is the sign function in Python?

Posted on Updated on

“OMG, Python doesn’t have a sign function”, I was almost about to say. I am fairly surprised there. It has surprised others too. My suggestion is.

def sign(x):
    if x > 0:
        return 1.
    elif x < 0:
        return -1.
    elif x == 0:
        return 0.
        return x

Almost the same as KonradVoelkel’s suggestion. Others suggest “just” using math.copysign available from Python 2.6:

def sign(x): return math.copysign(1, x)

However, this implementation returns funny things for NaN values, – not NaN that I would suspect. Another suggestion also in my opinion gives the“wrong” value for NaN (and here also zero has an issue):

def sign(x): return 1 if x >= 0 else -1

“elif x == 0: return 0.” is necessary if you want to return 0.0 from an input of -0.0.

My implementation seems to be in alignment with Matlab and Octave, though they handle string input differently. Here are some example calls to thefunction with numerical input:

>>> sign(-np.nan) 
>>> sign(np.nan) 
>>> sign(np.inf) 
>>> sign(-np.inf) 
>>> sign(-2) 
>>> sign(+2) 
>>> sign(+0.0) 
>>> sign(-0.0) 
>>> sign(-np.inf) 
>>> sign(np.inf) 

Update 20 May 2011: So one should think that such a simple function couldn’t go wrong, but did: For an empty list, sign([]), and for None, sign(None), the function produce inappropriate results. Furthermore an appropriate ‘sign’ function is defined in Numpy, e.g., np.sign(np.nan) works nicely.


4 thoughts on “Where is the sign function in Python?

    bruce said:
    July 11, 2016 at 8:18 am

    How about
    def SIGN(a, b):
    if b >= 0.0:
    return abs(a)
    return -abs(a)

      Finn Årup Nielsen responded:
      July 11, 2016 at 11:26 am

      This is not how the sign function is defined. The sign function returns either -1, 0 or +1.

        Finn Årup Nielsen responded:
        July 11, 2016 at 11:30 am

        if you call it with sign(1, x) then you end up with a wrong result for sign(1, 0).

    User said:
    August 18, 2016 at 11:08 am

    cmp(x, 0) is the most correct&short replacement for sign(x) with current Python (except for nan).

    But math.sign() should surely be implemented as it frequently needed in math oriented code.

    Note: There is no separate “-nan” . Any float operation on nan results in nan. nan does not compare equal to anything – not even to itself.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s