为什么Python没有符号功能? [英] Why doesn't Python have a sign function?

查看:124
本文介绍了为什么Python没有符号功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白为什么Python没有sign函数.它具有内置的abs(我认为是sign的姐姐),但没有sign.

在python 2.6中甚至还有一个copysign函数(在数学中),但没有迹象.当您只写一个sign然后直接从abs(x) * sign(y)获取copysign时,为什么还要写一个copysign(x,y)呢?后者要清楚得多:x带有y的符号,而带copysign的则必须记住它是x带有y的符号还是y带有x的符号!

很明显,sign(x)除了提供cmp(x,0)之外,没有提供其他任何功能,但是它也更具可读性(对于像python这样的易读性语言,这将是一个很大的优势).

如果我是python设计人员,那么我会反过来:没有内置的cmp,而是一个sign.当需要cmp(x,y)时,您可以执行sign(x-y)(或者,对于非数值的东西更好,只需x> y-当然,这应该要求sorted接受布尔值而不是整数比较器).这也将更加清晰:在x>y时为正(而对于cmp,您必须记住在更大时为正的约定,但可能是反之).当然,cmp出于其他原因(例如,在对非数字事物进行排序时,或者如果您希望排序是稳定的,仅使用布尔值是不可能的)就有意义了

因此,问题是:为什么Python设计人员决定将sign函数保留在语言之外?为什么要麻烦copysign而不是其父sign?

我想念什么吗?

编辑-在彼得·汉森(Peter Hansen)评论后. 足够公平,您没有使用它,但是您没有说您使用python做什么.在使用python的7年中,我无数次需要它,最后一个是打破骆驼后背的稻草!

是的,您可以传递cmp,但是我传递它的90%的时间是成语 lambda x,y: cmp(score(x),score(y))本来可以使用sign的.

最后,我希望您同意signcopysign有用,所以即使我购买了您的视图,为什么还要在数学中定义它而不是符号呢?复制符号比符号有什么用?

解决方案

确实有一个补丁,其中sign() docs.python.org/library/math.html#math.copysign"rel =" noreferrer>数学,但未被接受,因为他们不同意用来委派给最终用户-某些情况下所需的行为-有时可能需要调用cmp(x,0) .


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

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

最重要的是,copysignsign的超集!用x = 1调用copysignsign函数相同.因此,您可以只使用copysign忘记它.

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

如果您厌倦了传递两个完整的参数,则可以以这种方式实现sign,它仍将与其他人提到的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

第二,通常,当您需要某物的符号时,您最终会将其与另一个值相乘.当然,这基本上就是copysign的作用.

所以,而不是:

s = sign(a)
b = b * s

您可以这样做:

b = copysign(b, a)

是的,我很惊讶您使用Python已有7年了,认为cmp可以很容易地被删除并替换为sign!您是否从未使用__cmp__方法实现类?您是否从未调用cmp并指定了自定义比较器函数?

总而言之,我发现自己也想要一个sign函数,但是第一个参数为1的copysign可以正常工作.我不同意signcopysign有用,因为我已经证明它只是相同功能的一部分.

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.

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!

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

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)

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?

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!

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.

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?

解决方案

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)

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


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.

>>> 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:

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

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?

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.

这篇关于为什么Python没有符号功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆