我不明白为什么Python没有符号函数。它有腹肌(我认为它是sign的姐妹),但没有sign。

在python 2.6中,甚至有一个copysign函数(在数学中),但没有符号。当你可以只写一个符号,然后直接从abs(x) * sign(y)得到copyysign时,为什么还要麻烦写一个copyysign (x,y)呢?后者会更清楚:x和y的符号,而对于copysign,你必须记住它是x和y的符号还是y和x的符号!

显然,sign(x)提供的东西比cmp(x,0)多不了什么,但它的可读性也比这强得多(对于python这样可读性很强的语言来说,这将是一个很大的优点)。

If I were a python designer, I would been the other way arond: no cmp builtin, but a sign. When you need cmp(x,y), you could just do a sign(x-y) (or, even better for non-numerical stuff, just a x>y - of course this should have required sorted accepting a boolean instead of an integer comparator). This would also be more clear: positive when x>y (whereas with cmp you have to remember the convention positive when the first is bigger, but it could be the other way around). Of course cmp makes sense in its own for other reasons (e.g. when sorting non-numerical things, or if you want the sort to be stable, which is not possible using with simply a boolean)

那么,问题是:为什么Python设计者决定将符号函数排除在语言之外?为什么要麻烦复制符号而不是它的父符号呢?

我遗漏了什么吗?

编辑-在Peter Hansen评论之后。 很好,你没有使用它,但你没有说你用python做什么。在我使用python的7年里,我需要它无数次,最后一次是压垮骆驼的最后一根稻草!

是的,你可以传递cmp,但是90%的情况下,我需要传递的是一个成语 x,y: cmp(score(x) score(y))用符号就可以了。

最后,我希望你同意sign比copysign更有用,所以即使我同意你的观点,为什么要在数学中定义它,而不是sign呢?复印签名怎么比签名有用这么多?


当前回答

试着运行这个,其中x是任意数

int_sign = bool(x > 0) - bool(x < 0)

对bool()的强制转换处理比较运算符不返回布尔值的可能性。

其他回答

你不需要,你可以使用:

if not number == 0:
    sig = number/abs(number)
else:
    sig = 0

或者创建其他人描述的函数:

sign = lambda x: bool(x > 0) - bool(x < 0)

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

Numpy有一个符号函数,并为您提供了其他函数。所以:

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

只是要注意结果是numpy.float64:

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

对于json之类的东西,这很重要,因为json不知道如何序列化numpy。float64类型。在这种情况下,你可以这样做:

float(np.sign(y))

得到一个常规的浮动。

在Python 2中,cmp()返回一个整数:不要求结果是-1、0或1,因此sign(x)与cmp(x,0)不同。

在Python 3中,cmp()已被删除,以支持丰富的比较。对于cmp(), Python 3建议这样做:

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

这适用于cmp(),但同样不能用于sign(),因为比较操作符不需要返回布尔值。

为了处理这种可能性,比较结果必须被强制为布尔值:

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

这适用于任何完全有序的类型(包括NaN或无穷大等特殊值)。

维基百科上的定义如下:

因此,为了符合定义:

sign = lambda x: -1 if x < 0 else (1 if x > 0 else (0 if x == 0 else NaN))

就所有意图和目的而言,可以简化为:

sign = lambda x: -1 if x < 0 else (1 if x > 0 else 0)

这个函数定义执行速度很快,并保证得到0、0.0、-0.0、-4和5的正确结果(请参阅其他错误答案的注释)。

注意,零(0)既不是正的也不是负的。

由于cmp已被删除,您可以使用

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

def sign(a):
    return (a > 0) - (a < 0)

它适用于float, int和Fraction。在float的情况下,注意sign(float("nan"))为零。

Python不要求比较返回布尔值,因此将比较强制为bool()可以防止允许但不常见的实现:

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