为什么Python没有符号函数?

时间:2022-04-17 22:01:42

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 sign.

我不明白为什么Python没有符号函数。它有一个abs内置的(我认为是它的妹妹),但是没有标识。

In python 2.6 there is even a copysign function (in math), but no sign. Why bother to write a copysign(x,y) when you could just write a sign and then get the copysign directly from abs(x) * sign(y)? The latter would be much more clear: x with the sign of y, whereas with copysign you have to remember if it's x with the sign of y or y with the sign of x!

在python 2.6中甚至有一个copysign函数(在数学中),但是没有符号。当你只需要写一个符号,然后直接从abs(x) *符号(y)得到copysign的时候,为什么要写一个copysign(x,y)呢?后者会更清晰:x有y的符号,而copysign你必须记住,如果它是x的符号y或y的符号x!

Obviously sign(x) does not provide anything more than cmp(x,0), but it would be much more readable that this too (and for a greatly readable language like python, this would have been a big plus).

显然,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设计师,我将会是另一种方式:没有cmp构建,而是一个符号。当你需要cmp(x,y)时,你可以只做一个符号(x-y)(或者,对非数值的东西更好,只是一个x>y -当然,这应该是需要排序的接受一个布尔而不是整数比较器)。这一点也更清楚:当x>y(而cmp的时候,你必须记住,当第一个符号更大时,它是正的,但它可能是相反的)。当然,cmp由于其他原因也有意义(例如,当对非数值的东西进行排序时,或者如果您希望排序是稳定的,这是不可能的,仅仅使用一个布尔值)

So, the question is: why did the Python designer(s) decide to leave the sign function out of the language? Why the heck bother with copysign and not its parent sign?

所以,问题是:为什么Python设计者决定将符号函数从语言中去掉?为什么会讨厌copysign而不是它的父符号呢?

Am I missing something?

我遗漏了什么东西?

EDIT - after Peter Hansen comment. Fair enough that you didn't use it, but you didn't say what you use python for. In 7 years that I use python, I needed it countless times, and the last is the straw that broke the camel's back!

编辑——彼得·汉森的评论。很好,你没有使用它,但是你没有说你用python做什么。在我使用python的7年里,我无数次地需要它,最后一根稻草压垮骆驼的脊背!

Yes, you can pass cmp around, but 90% of the times that I needed to pass it was in an idiom like lambda x,y: cmp(score(x),score(y)) that would have worked with sign just fine.

是的,你可以通过cmp,但是90%的时间我需要传递的是一个习语,比如,x,y: cmp(score(x),score(y)),这样就可以很好地工作了。

Finally, I hope you agree that sign would be more useful than copysign, so even if I bought your view, why bother about defining that in math, instead of sign? How can copysign be so much useful than sign?

最后,我希望你同意这个符号比copysign更有用,所以即使我买了你的观点,为什么要用数学来定义它,而不是符号?copysign怎么能比sign更有用呢?

10 个解决方案

#1


175  

EDIT:

编辑:

Indeed there was a patch which included sign() in math, but it wasn't accepted, because they didn't agree on what it should return in all the edge cases (+/-0, +/-nan, etc)

实际上,在数学中有一个包含sign()的补丁,但是它不被接受,因为他们不同意在所有的边界情况下它应该返回什么(+/-0,+/-nan等等)

So they decided to implement only copysign, which (although more verbose) can be used to delegate to the end user the desired behavior for edge cases - which sometimes might require the call to cmp(x,0).

因此,他们决定只实现copysign,它(尽管更详细)可以用来委托给最终用户的边界情况所需的行为——有时可能需要调用cmp(x,0)。


I don't know why it's not a built-in, but I have some thoughts.

我不知道为什么它不是内置的,但我有一些想法。

copysign(x,y):
Return x with the sign of y.

Most importantly, copysign is a superset of sign! Calling copysign with x=1 is the same as a sign function. So you could just use copysign and forget about it.

最重要的是,copysign是一个超级符号!使用x=1调用copysign与符号函数相同。所以你可以使用copysign,然后忘记它。

>>> math.copysign(1, -4)
-1.0
>>> math.copysign(1, 3)
1.0

If you get sick of passing two whole arguments, you can implement sign this way, and it will still be compatible with the IEEE stuff mentioned by others:

如果您厌倦了传递两个完整的参数,您可以通过这种方式实现签名,并且它仍然与其他的IEEE内容兼容:

>>> sign = functools.partial(math.copysign, 1) # either of these
>>> sign = lambda x: math.copysign(1, x) # two will work
>>> sign(-4)
-1.0
>>> sign(3)
1.0
>>> sign(0)
1.0
>>> sign(-0.0)
-1.0
>>> sign(float('nan'))
-1.0

Secondly, usually when you want the sign of something, you just end up multiplying it with another value. And of course that's basically what copysign does.

第二,通常当你想要某个东西的符号时,你最终会把它与另一个值相乘。这基本上就是copysign所做的。

So, instead of:

因此,而不是:

s = sign(a)
b = b * s

You can just do:

你可以做的:

b = copysign(b, a)

And yes, I'm surprised you've been using Python for 7 years and think cmp could be so easily removed and replaced by sign! Have you never implemented a class with a __cmp__ method? Have you never called cmp and specified a custom comparator function?

是的,我很惊讶你已经用了7年的Python,并且认为cmp很容易被删除并被符号代替!您从未使用__cmp__方法实现类吗?您是否从未调用cmp并指定自定义比较器函数?

In summary, I've found myself wanting a sign function too, but copysign with the first argument being 1 will work just fine. I disagree that sign would be more useful than copysign, as I've shown that it's merely a subset of the same functionality.

总之,我发现自己也想要一个符号函数,但是第一个参数为1的copysign将会工作得很好。我不同意这个符号会比copysign更有用,因为我已经证明它只是相同功能的一个子集。

#2


51  

"copysign" is defined by IEEE 754, and part of the C99 specification. That's why it's in Python. The function cannot be implemented in full by abs(x) * sign(y) because of how it's supposed to handle NaN values.

“copysign”由IEEE 754和C99规范的一部分定义。这就是它在Python里的原因。由于它应该如何处理NaN值,所以不能用abs(x) *符号(y)来实现这个函数。

>>> import math
>>> math.copysign(1, float("nan"))
1.0
>>> math.copysign(1, float("-nan"))
-1.0
>>> math.copysign(float("nan"), 1)
nan
>>> math.copysign(float("nan"), -1)
nan
>>> float("nan") * -1
nan
>>> float("nan") * 1
nan
>>> 

That makes copysign() a more useful function than sign().

这使得copysign()比sign()更有用。

As to specific reasons why IEEE's signbit(x) is not available in standard Python, I don't know. I can make assumptions, but it would be guessing.

至于IEEE的signbit(x)在标准Python中不可用的具体原因,我不知道。我可以做假设,但这是猜测。

The math module itself uses signbit(1, x) as a way to check if x is negative or non-negative. For most cases dealing with mathematical functions that seems more useful than having a sign(x) which returns 1, 0, or -1 because there's one less case to consider. For example, the following is from Python's math module:

math模块本身使用signbit(1, x)作为检查x是否为负或非负的方法。在大多数情况下,处理数学函数似乎比用符号(x)返回1、0或-1更有用,因为有一个更少的例子需要考虑。例如,以下是Python的数学模块:

static double
m_atan2(double y, double x)
{
        if (Py_IS_NAN(x) || Py_IS_NAN(y))
                return Py_NAN;
        if (Py_IS_INFINITY(y)) {
                if (Py_IS_INFINITY(x)) {
                        if (copysign(1., x) == 1.)
                                /* atan2(+-inf, +inf) == +-pi/4 */
                                return copysign(0.25*Py_MATH_PI, y);
                        else
                                /* atan2(+-inf, -inf) == +-pi*3/4 */
                                return copysign(0.75*Py_MATH_PI, y);
                }
                /* atan2(+-inf, x) == +-pi/2 for finite x */
                return copysign(0.5*Py_MATH_PI, y);

There you can clearly see that copysign() is a more effective function than a three-valued sign() function.

在这里,您可以清楚地看到copysign()是一个比三值符号()函数更有效的函数。

You wrote:

你写的:

If I were a python designer, I would been the other way arond: no cmp() builtin, but a sign()

如果我是python设计人员,我将会是另一种方式:没有cmp()构建,而是一个符号()

That means you don't know that cmp() is used for things besides numbers. cmp("This", "That") cannot be implemented with a sign() function.

这意味着您不知道cmp()是用于除数字之外的东西。cmp(“This”,“That”)不能用符号()函数来实现。

Edit to collate my additional answers elsewhere:

编辑整理我在其他地方的附加答案:

You base your justifications on how abs() and sign() are often seen together. As the C standard library does not contain a 'sign(x)' function of any sort, I don't know how you justify your views. There's an abs(int) and fabs(double) and fabsf(float) and fabsl(long) but no mention of sign. There is "copysign()" and "signbit()" but those only apply to IEEE 754 numbers.

你的理由基于abs()和sign()经常在一起被看到。由于C标准库不包含任何类型的“符号(x)”功能,所以我不知道您如何为您的视图辩护。有一个abs(int)和fabs(double)和fabsf(float)和fabsl(long),但没有提到符号。有“copysign()”和“signbit()”,但这些只适用于IEEE 754号。

With complex numbers, what would sign(-3+4j) return in Python, were it to be implemented? abs(-3+4j) return 5.0. That's a clear example of how abs() can be used in places where sign() makes no sense.

有了复杂的数字,在Python中会有什么(-3+4j)返回,是要实现吗?abs(3 + 4 j)返回5.0。这是abs()如何在没有意义的地方使用的一个很明显的例子。

Suppose sign(x) were added to Python, as a complement to abs(x). If 'x' is an instance of a user-defined class which implements the __abs__(self) method then abs(x) will call x.__abs__(). In order to work correctly, to handle abs(x) in the same way then Python will have to gain a sign(x) slot.

假设将符号(x)添加到Python中,作为abs(x)的补充。如果“x”是一个用户定义类的实例,它实现了__abs__(self)方法,那么abs(x)将调用x.__abs__()。为了正确地工作,以同样的方式处理abs(x),那么Python必须获得一个符号(x)槽。

This is excessive for a relatively unneeded function. Besides, why should sign(x) exist and nonnegative(x) and nonpositive(x) not exist? My snippet from Python's math module implementation shows how copybit(x, y) can be used to implement nonnegative(), which a simple sign(x) cannot do.

这对于一个相对不需要的函数来说是多余的。此外,为什么要存在符号(x)和非负(x)和非正(x)不存在?我从Python的math模块实现中得到的代码片段显示了copybit(x, y)如何被用于实现非负(),这是一个简单的符号(x)不能做的事情。

Python should support have better support for IEEE 754/C99 math function. That would add a signbit(x) function, which would do what you want in the case of floats. It would not work for integers or complex numbers, much less strings, and it wouldn't have the name you are looking for.

Python应该支持更好地支持IEEE 754/C99数学函数。这将添加一个signbit(x)函数,它将在浮动的情况下做您想做的事情。它不适合整数或复数,更少的字符串,它也不会有你要找的名字。

You ask "why", and the answer is "sign(x) isn't useful." You assert that it is useful. Yet your comments show that you do not know enough to be able to make that assertion, which means you would have to show convincing evidence of its need. Saying that NumPy implements it is not convincing enough. You would need to show cases of how existing code would be improved with a sign function.

你问“为什么”,答案是“符号(x)没用。”你断言它是有用的。然而,你的评论表明你还不知道如何做出这种断言,这意味着你必须拿出令人信服的证据来证明它的必要性。说NumPy实现它还不够有说服力。您需要展示如何使用符号函数改进现有代码的情况。

And that it outside the scope of *. Take it instead to one of the Python lists.

它超出了*的范围。把它改为一个Python列表。

#3


29  

Another one liner for sign()

另一艘船旗()

sign = lambda x: (1, -1)[x<0]

If you want it to return 0 for x = 0:

如果你想让x = 0返回0:

sign = lambda x: x and (1, -1)[x<0]

#4


17  

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

由于cmp已被删除,您可以使用相同的功能。

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.

它适用于浮点,整数,甚至分数。在浮动的情况下,注意符号(float(“nan”))为零。

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

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

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

#5


8  

Try running this, where x is any number

试试运行这个,x是任意数字。

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

The coercion to bool() handles the possibility that the comparison operator doesn't return a boolean.

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

#6


6  

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

numpy有一个符号函数,它还会给你其他函数的额外好处。所以:

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

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

只是要小心,结果是一个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:

对于json之类的问题,json不知道如何序列化numpy。float64类型。在这种情况下,你可以这样做:

float(np.sign(y))

to get a regular float.

得到一个规则的浮点数。

#7


2  

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.

是的,一个正确的符号()函数应该至少在数学模块中——因为它是在numpy中。因为人们经常需要它来编写面向数学的代码。

But math.copysign() is also useful independently.

但是,math.copysign()也可以独立使用。

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

cmp()和obj.__cmp__()……具有高度的独立性。不仅仅是面向数学的代码。考虑比较/分类元组,日期对象,…

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

关于math.sign()的不作为,在http://bugs.python.org/e1640上的dev参数是奇数,因为:

  • There is no separate -NaN
  • 没有单独的-NaN。
  • sign(nan) == nan without worry (like exp(nan) )
  • (nan) == nan不用担心(如exp(nan))
  • sign(-0.0) == sign(0.0) == 0 without worry
  • 符号(-0.0)== == = 0,不用担心。
  • sign(-inf) == -1 without worry
  • 符号(-inf) == -1,不用担心。

-- as it is in numpy

——因为它是麻木的。

#8


1  

You dont need one, you can just use:

你不需要,你可以用:

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

#9


1  

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).

在Python 2中,cmp()返回一个整数:没有要求结果是-1、0或1,所以符号(x)不等于cmp(x,0)。

In Python 3, cmp() has been removed in favor of rich comparison. For cmp(), Python 3 suggests (https://docs.python.org/3/whatsnew/3.0.html):

在Python 3中,cmp()已被删除,以支持丰富的比较。对于cmp(), Python 3建议(https://docs.python.org/3/whatsnew/3.0.html):

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 (https://docs.python.org/3/reference/datamodel.html#object.lt).

这对于cmp()来说是很好的,但是同样不能用于符号(),因为比较操作符不需要返回布尔值(https://docs.python.org/3/reference/datamodel.html#object.lt)。

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

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

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

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

这适用于任何完全有序的类型(包括像NaN或infinities这样的特殊值)。

#10


-6  

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.

不包括“sign”的原因是,如果我们在内置函数列表中包含了所有有用的一行程序,那么Python就不容易和实际工作了。如果你经常使用这个函数,那么你为什么不把它提出来呢?这样做并不困难,甚至是乏味的。

#1


175  

EDIT:

编辑:

Indeed there was a patch which included sign() in math, but it wasn't accepted, because they didn't agree on what it should return in all the edge cases (+/-0, +/-nan, etc)

实际上,在数学中有一个包含sign()的补丁,但是它不被接受,因为他们不同意在所有的边界情况下它应该返回什么(+/-0,+/-nan等等)

So they decided to implement only copysign, which (although more verbose) can be used to delegate to the end user the desired behavior for edge cases - which sometimes might require the call to cmp(x,0).

因此,他们决定只实现copysign,它(尽管更详细)可以用来委托给最终用户的边界情况所需的行为——有时可能需要调用cmp(x,0)。


I don't know why it's not a built-in, but I have some thoughts.

我不知道为什么它不是内置的,但我有一些想法。

copysign(x,y):
Return x with the sign of y.

Most importantly, copysign is a superset of sign! Calling copysign with x=1 is the same as a sign function. So you could just use copysign and forget about it.

最重要的是,copysign是一个超级符号!使用x=1调用copysign与符号函数相同。所以你可以使用copysign,然后忘记它。

>>> math.copysign(1, -4)
-1.0
>>> math.copysign(1, 3)
1.0

If you get sick of passing two whole arguments, you can implement sign this way, and it will still be compatible with the IEEE stuff mentioned by others:

如果您厌倦了传递两个完整的参数,您可以通过这种方式实现签名,并且它仍然与其他的IEEE内容兼容:

>>> sign = functools.partial(math.copysign, 1) # either of these
>>> sign = lambda x: math.copysign(1, x) # two will work
>>> sign(-4)
-1.0
>>> sign(3)
1.0
>>> sign(0)
1.0
>>> sign(-0.0)
-1.0
>>> sign(float('nan'))
-1.0

Secondly, usually when you want the sign of something, you just end up multiplying it with another value. And of course that's basically what copysign does.

第二,通常当你想要某个东西的符号时,你最终会把它与另一个值相乘。这基本上就是copysign所做的。

So, instead of:

因此,而不是:

s = sign(a)
b = b * s

You can just do:

你可以做的:

b = copysign(b, a)

And yes, I'm surprised you've been using Python for 7 years and think cmp could be so easily removed and replaced by sign! Have you never implemented a class with a __cmp__ method? Have you never called cmp and specified a custom comparator function?

是的,我很惊讶你已经用了7年的Python,并且认为cmp很容易被删除并被符号代替!您从未使用__cmp__方法实现类吗?您是否从未调用cmp并指定自定义比较器函数?

In summary, I've found myself wanting a sign function too, but copysign with the first argument being 1 will work just fine. I disagree that sign would be more useful than copysign, as I've shown that it's merely a subset of the same functionality.

总之,我发现自己也想要一个符号函数,但是第一个参数为1的copysign将会工作得很好。我不同意这个符号会比copysign更有用,因为我已经证明它只是相同功能的一个子集。

#2


51  

"copysign" is defined by IEEE 754, and part of the C99 specification. That's why it's in Python. The function cannot be implemented in full by abs(x) * sign(y) because of how it's supposed to handle NaN values.

“copysign”由IEEE 754和C99规范的一部分定义。这就是它在Python里的原因。由于它应该如何处理NaN值,所以不能用abs(x) *符号(y)来实现这个函数。

>>> import math
>>> math.copysign(1, float("nan"))
1.0
>>> math.copysign(1, float("-nan"))
-1.0
>>> math.copysign(float("nan"), 1)
nan
>>> math.copysign(float("nan"), -1)
nan
>>> float("nan") * -1
nan
>>> float("nan") * 1
nan
>>> 

That makes copysign() a more useful function than sign().

这使得copysign()比sign()更有用。

As to specific reasons why IEEE's signbit(x) is not available in standard Python, I don't know. I can make assumptions, but it would be guessing.

至于IEEE的signbit(x)在标准Python中不可用的具体原因,我不知道。我可以做假设,但这是猜测。

The math module itself uses signbit(1, x) as a way to check if x is negative or non-negative. For most cases dealing with mathematical functions that seems more useful than having a sign(x) which returns 1, 0, or -1 because there's one less case to consider. For example, the following is from Python's math module:

math模块本身使用signbit(1, x)作为检查x是否为负或非负的方法。在大多数情况下,处理数学函数似乎比用符号(x)返回1、0或-1更有用,因为有一个更少的例子需要考虑。例如,以下是Python的数学模块:

static double
m_atan2(double y, double x)
{
        if (Py_IS_NAN(x) || Py_IS_NAN(y))
                return Py_NAN;
        if (Py_IS_INFINITY(y)) {
                if (Py_IS_INFINITY(x)) {
                        if (copysign(1., x) == 1.)
                                /* atan2(+-inf, +inf) == +-pi/4 */
                                return copysign(0.25*Py_MATH_PI, y);
                        else
                                /* atan2(+-inf, -inf) == +-pi*3/4 */
                                return copysign(0.75*Py_MATH_PI, y);
                }
                /* atan2(+-inf, x) == +-pi/2 for finite x */
                return copysign(0.5*Py_MATH_PI, y);

There you can clearly see that copysign() is a more effective function than a three-valued sign() function.

在这里,您可以清楚地看到copysign()是一个比三值符号()函数更有效的函数。

You wrote:

你写的:

If I were a python designer, I would been the other way arond: no cmp() builtin, but a sign()

如果我是python设计人员,我将会是另一种方式:没有cmp()构建,而是一个符号()

That means you don't know that cmp() is used for things besides numbers. cmp("This", "That") cannot be implemented with a sign() function.

这意味着您不知道cmp()是用于除数字之外的东西。cmp(“This”,“That”)不能用符号()函数来实现。

Edit to collate my additional answers elsewhere:

编辑整理我在其他地方的附加答案:

You base your justifications on how abs() and sign() are often seen together. As the C standard library does not contain a 'sign(x)' function of any sort, I don't know how you justify your views. There's an abs(int) and fabs(double) and fabsf(float) and fabsl(long) but no mention of sign. There is "copysign()" and "signbit()" but those only apply to IEEE 754 numbers.

你的理由基于abs()和sign()经常在一起被看到。由于C标准库不包含任何类型的“符号(x)”功能,所以我不知道您如何为您的视图辩护。有一个abs(int)和fabs(double)和fabsf(float)和fabsl(long),但没有提到符号。有“copysign()”和“signbit()”,但这些只适用于IEEE 754号。

With complex numbers, what would sign(-3+4j) return in Python, were it to be implemented? abs(-3+4j) return 5.0. That's a clear example of how abs() can be used in places where sign() makes no sense.

有了复杂的数字,在Python中会有什么(-3+4j)返回,是要实现吗?abs(3 + 4 j)返回5.0。这是abs()如何在没有意义的地方使用的一个很明显的例子。

Suppose sign(x) were added to Python, as a complement to abs(x). If 'x' is an instance of a user-defined class which implements the __abs__(self) method then abs(x) will call x.__abs__(). In order to work correctly, to handle abs(x) in the same way then Python will have to gain a sign(x) slot.

假设将符号(x)添加到Python中,作为abs(x)的补充。如果“x”是一个用户定义类的实例,它实现了__abs__(self)方法,那么abs(x)将调用x.__abs__()。为了正确地工作,以同样的方式处理abs(x),那么Python必须获得一个符号(x)槽。

This is excessive for a relatively unneeded function. Besides, why should sign(x) exist and nonnegative(x) and nonpositive(x) not exist? My snippet from Python's math module implementation shows how copybit(x, y) can be used to implement nonnegative(), which a simple sign(x) cannot do.

这对于一个相对不需要的函数来说是多余的。此外,为什么要存在符号(x)和非负(x)和非正(x)不存在?我从Python的math模块实现中得到的代码片段显示了copybit(x, y)如何被用于实现非负(),这是一个简单的符号(x)不能做的事情。

Python should support have better support for IEEE 754/C99 math function. That would add a signbit(x) function, which would do what you want in the case of floats. It would not work for integers or complex numbers, much less strings, and it wouldn't have the name you are looking for.

Python应该支持更好地支持IEEE 754/C99数学函数。这将添加一个signbit(x)函数,它将在浮动的情况下做您想做的事情。它不适合整数或复数,更少的字符串,它也不会有你要找的名字。

You ask "why", and the answer is "sign(x) isn't useful." You assert that it is useful. Yet your comments show that you do not know enough to be able to make that assertion, which means you would have to show convincing evidence of its need. Saying that NumPy implements it is not convincing enough. You would need to show cases of how existing code would be improved with a sign function.

你问“为什么”,答案是“符号(x)没用。”你断言它是有用的。然而,你的评论表明你还不知道如何做出这种断言,这意味着你必须拿出令人信服的证据来证明它的必要性。说NumPy实现它还不够有说服力。您需要展示如何使用符号函数改进现有代码的情况。

And that it outside the scope of *. Take it instead to one of the Python lists.

它超出了*的范围。把它改为一个Python列表。

#3


29  

Another one liner for sign()

另一艘船旗()

sign = lambda x: (1, -1)[x<0]

If you want it to return 0 for x = 0:

如果你想让x = 0返回0:

sign = lambda x: x and (1, -1)[x<0]

#4


17  

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

由于cmp已被删除,您可以使用相同的功能。

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.

它适用于浮点,整数,甚至分数。在浮动的情况下,注意符号(float(“nan”))为零。

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

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

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

#5


8  

Try running this, where x is any number

试试运行这个,x是任意数字。

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

The coercion to bool() handles the possibility that the comparison operator doesn't return a boolean.

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

#6


6  

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

numpy有一个符号函数,它还会给你其他函数的额外好处。所以:

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

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

只是要小心,结果是一个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:

对于json之类的问题,json不知道如何序列化numpy。float64类型。在这种情况下,你可以这样做:

float(np.sign(y))

to get a regular float.

得到一个规则的浮点数。

#7


2  

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.

是的,一个正确的符号()函数应该至少在数学模块中——因为它是在numpy中。因为人们经常需要它来编写面向数学的代码。

But math.copysign() is also useful independently.

但是,math.copysign()也可以独立使用。

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

cmp()和obj.__cmp__()……具有高度的独立性。不仅仅是面向数学的代码。考虑比较/分类元组,日期对象,…

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

关于math.sign()的不作为,在http://bugs.python.org/e1640上的dev参数是奇数,因为:

  • There is no separate -NaN
  • 没有单独的-NaN。
  • sign(nan) == nan without worry (like exp(nan) )
  • (nan) == nan不用担心(如exp(nan))
  • sign(-0.0) == sign(0.0) == 0 without worry
  • 符号(-0.0)== == = 0,不用担心。
  • sign(-inf) == -1 without worry
  • 符号(-inf) == -1,不用担心。

-- as it is in numpy

——因为它是麻木的。

#8


1  

You dont need one, you can just use:

你不需要,你可以用:

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

#9


1  

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).

在Python 2中,cmp()返回一个整数:没有要求结果是-1、0或1,所以符号(x)不等于cmp(x,0)。

In Python 3, cmp() has been removed in favor of rich comparison. For cmp(), Python 3 suggests (https://docs.python.org/3/whatsnew/3.0.html):

在Python 3中,cmp()已被删除,以支持丰富的比较。对于cmp(), Python 3建议(https://docs.python.org/3/whatsnew/3.0.html):

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 (https://docs.python.org/3/reference/datamodel.html#object.lt).

这对于cmp()来说是很好的,但是同样不能用于符号(),因为比较操作符不需要返回布尔值(https://docs.python.org/3/reference/datamodel.html#object.lt)。

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

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

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

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

这适用于任何完全有序的类型(包括像NaN或infinities这样的特殊值)。

#10


-6  

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.

不包括“sign”的原因是,如果我们在内置函数列表中包含了所有有用的一行程序,那么Python就不容易和实际工作了。如果你经常使用这个函数,那么你为什么不把它提出来呢?这样做并不困难,甚至是乏味的。