“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. else: return x
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) nan >>> sign(np.nan) nan >>> sign(np.inf) 1.0 >>> sign(-np.inf) -1.0 >>> sign(-2) -1.0 >>> sign(+2) 1.0 >>> sign(+0.0) 0.0 >>> sign(-0.0) 0.0 >>> sign(-np.inf) -1.0 >>> sign(np.inf) 1.0
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.