Why doesn't Python have a sign function?

前端 未结 12 666
旧巷少年郎
旧巷少年郎 2020-12-02 04:54

I can\'t understand why Python doesn\'t have a sign function. It has an abs builtin (which I consider sign\'s sister), but no si

相关标签:
12条回答
  • 2020-12-02 05:05

    numpy has a sign function, and gives you a bonus of other functions as well. So:

    import numpy as np
    x = np.sign(y)
    

    Just be careful that the result is a numpy.float64:

    >>> type(np.sign(1.0))
    <type 'numpy.float64'>
    

    For things like json, this matters, as json does not know how to serialize numpy.float64 types. In that case, you could do:

    float(np.sign(y))
    

    to get a regular float.

    0 讨论(0)
  • 2020-12-02 05:06

    Since cmp has been removed, you can get the same functionality with

    def cmp(a, b):
        return (a > b) - (a < b)
    
    def sign(a):
        return (a > 0) - (a < 0)
    

    It works for float, int and even Fraction. In the case of float, notice sign(float("nan")) is zero.

    Python doesn't require that comparisons return a boolean, and so coercing the comparisons to bool() protects against allowable, but uncommon implementation:

    def sign(a):
        return bool(a > 0) - bool(a < 0)
    
    0 讨论(0)
  • 2020-12-02 05:06

    In Python 2, cmp() returns an integer: there's no requirement that the result be -1, 0, or 1, so sign(x) is not the same as cmp(x,0).

    In Python 3, cmp() has been removed in favor of rich comparison. For cmp(), Python 3 suggests this:

    def cmp(a, b):
        return (a > b) - (a < b)
    

    which is fine for cmp(), but again can't be used for sign() because the comparison operators need not return booleans.

    To deal with this possibility, the comparison results must be coerced to booleans:

     def sign(x):
        return bool(x > 0) - bool(x < 0)
    

    This works for any type which is totally ordered (including special values like NaN or infinities).

    0 讨论(0)
  • 2020-12-02 05:16

    The reason "sign" is not included is that if we included every useful one-liner in the list of built-in functions, Python wouldn't be easy and practical to work with anymore. If you use this function so often then why don't you do factor it out yourself? It's not like it's remotely hard or even tedious to do so.

    0 讨论(0)
  • 2020-12-02 05:20

    Yes a correct sign() function should be at least in the math module - as it is in numpy. Because one frequently needs it for math oriented code.

    But math.copysign() is also useful independently.

    cmp() and obj.__cmp__() ... have generally high importance independently. Not just for math oriented code. Consider comparing/sorting tuples, date objects, ...

    The dev arguments at http://bugs.python.org/issue1640 regarding the omission of math.sign() are odd, because:

    • There is no separate -NaN
    • sign(nan) == nan without worry (like exp(nan) )
    • sign(-0.0) == sign(0.0) == 0 without worry
    • sign(-inf) == -1 without worry

    -- as it is in numpy

    0 讨论(0)
  • 2020-12-02 05:21

    It just doesn't.

    The best way to fix this is:

    sign = lambda x: bool(x > 0) - bool(x < 0)
    
    0 讨论(0)
提交回复
热议问题