Pourquoi ne pas Python ont une fonction de signe?
Je ne comprends pas pourquoi Python n'est pas un sign
fonction. Il a une abs
builtin (que je considère sign
's sister), mais pas de sign
.
En python 2.6, il existe même un copysign
fonction (en mathématiques), mais aucun signe. Pourquoi s'embêter à écrire un copysign(x,y)
quand vous pourriez écrire un sign
, puis obtenir le copysign
directement à partir de abs(x) * sign(y)
? Celui-ci serait beaucoup plus clair: x avec le signe de y, alors qu'avec copysign vous devez vous rappeler si c'est x avec le signe de y ou y avec le signe de x!
Évidemment sign(x)
ne fournit pas quelque chose de plus que cmp(x,0)
, mais il serait beaucoup plus lisible que ce trop (et pour un très lisible langage comme python, cela aurait été un gros plus).
Si j'étais un python designer, j'aurais été dans l'autre façon arond: pas de cmp
builtin, mais un sign
. Lorsque vous avez besoin cmp(x,y)
, vous pourriez faire un sign(x-y)
(ou, encore mieux pour les non-numérique tout ça, juste un x>y - bien sûr, cela aurait exigé sorted
acceptant un booléen au lieu d'un entier comparateur). Cela permettrait aussi d'être plus clair: positif quand x>y
(alors qu'avec cmp
vous devez vous rappeler de la convention positif lorsque le première est plus, mais il pourrait être dans l'autre sens). Bien sûr cmp
de sens que dans son propre pour d'autres raisons (par exemple, lors d'un tri numérique non-choses, ou si vous voulez du genre à être stable, ce qui n'est pas possible en utilisant simplement un booléen)
Donc, la question est: pourquoi le Python concepteur(s) de décider de quitter l' sign
fonction de la langue? Pourquoi diable s'embêter avec copysign
et pas son parent sign
?
Suis-je raté quelque chose?
EDIT - après Peter Hansen commentaire.
Juste assez que vous n'avez pas l'utiliser, mais vous n'avez pas dit ce que vous utilisez python pour. En 7 ans que j'utilise python, j'ai besoin de nombreuses fois, et la dernière est la goutte d'eau qui a fait déborder le vase!
Oui, vous pouvez passer cmp autour, mais 90% du temps que je devais passer un langage comme
lambda x,y: cmp(score(x),score(y))
qui ont travaillé avec le signe de l'amende juste.
Enfin, j'espère que vous conviendrez que sign
serait plus utile que copysign
, de sorte que même si j'ai acheté votre avis, pourquoi s'embêter à propos de la définition qu'en mathématiques, au lieu du signe? Comment peut-copysign être tellement utile que de signer?
- "Suis-je raté quelque chose?" Si rien d'autre, le fait que l'utilisation de
sign(x-y)
exige une expression être évalués, ce qui signifie que vous ne pouvez pas passer comme un rappel à moins que vous l'envelopper dans un "partielle" de la première. Avec cmp() tel que défini, vous venez de passer une référence àcmp
autour. Aussi "extrêmement utile"? J'en doute. J'ai eu un besoin pour qu'une fois en 10 ans de l'écrit en Python. Si c'était vraiment utile, je pense qu'il serait là... - ne serait-ce pas l'argument de travail pour toutes les questions sur ce site? il suffit de fermer stackoverflow et poser toutes les questions au sujet pertinent dev utilisateur ou de la liste de diffusion!
- D'abord je suis d'accord, un signum fonction est pratique et utile. Deuxièmement, je suis d'accord avec dmazzoni dans que votre question est préférable de poser sur python-dev. C'est une chose à vous demander comment utiliser une liste de compréhension à faire xyz: nous pouvons faire un bon travail de répondre ici. Mais de se demander pourquoi Guido Van Rossum gauche signum est difficile pour quelqu'un ici à la réponse.
- Le bon endroit pour une question est tout endroit où il est susceptible d'être répondu. Ainsi, stackoverflow est un endroit approprié.
- J'ai utilisé Python pour à peu près toute forme de logiciel il y a, littéralement. Je ne travaille pas exclusivement dans une région où le signe() serait donc utile. Vous semble; les développeurs ne sont manifestement pas. Comme il a été noté, si vous voulez vraiment la réponse, allez demander où sont les développeurs eux-mêmes traîner, et vous allez en prendre plein les oreilles.
- -1: @Davide: "Pourquoi" et le "pourquoi pas" les questions ne peuvent être traitées ici. Puisque la plupart des directeurs d'école, de développement Python ne pas répondre à des questions ici, vous êtes rarement (voire jamais) pour obtenir une réponse à un "pourquoi" ou "pourquoi pas" en question. De plus, vous n'avez pas de problème à résoudre. Vous semblez avoir un coup de gueule. Si vous avez un problème ("Comment puis-je contourner l'absence de signe dans cet exemple...") qui est raisonnable. "Pourquoi pas" n'est pas raisonnable pour ce lieu.
- Puisque vous demandez pourquoi quelqu'un créé quelque chose d'une manière particulière, pourquoi ne pas demander directement le graphiste? En essayant d'amener les autres à spéculer n'est pas particulièrement utile.
- La question est peut-être un peu ému, mais je ne pense pas que c'est une mauvaise question. Je suis sûr que beaucoup de gens ont cherché un construit-dans la fonction de signe, de sorte qu'il peut être curieux de savoir pourquoi il n'existe pas.
- C'est bon d'être curieux. Mais vous êtes très peu de chances d'obtenir une réponse ici. Alors allez être curieux de tout autre endroit où vous obtiendrez une réponse.
- C'est parfaitement objectif de la question: “Pourquoi” Python est dépourvue de tout élément donné est légitime requête à propos de l'histoire de la langue de conception qui peut être répondu par un lien vers la discussion appropriée à partir de python-dev ou d'autres forums (parfois billets de blog) où le Python de base aux développeurs de se produire pour de hachage d'un sujet. Après avoir essayé de Google pour les bits de l'histoire de python-dev moi-même avant, je peux comprendre pourquoi un nouveau venu dans la langue pourrait frapper une impasse et venez poser ici dans l'espoir d'une plus expérimentés Python personne qui répond!
Vous devez vous connecter pour publier un commentaire.
EDIT:
En effet il y avait un patch qui inclus
sign()
dans mathématiques, mais il n'était pas accepté, parce qu'ils n'étaient pas d'accord sur ce qu'il doit retourner dans tous les cas de bord (+/-0, +/-nan, etc)Ils ont donc décidé de mettre en œuvre seul copysign, qui (bien que plus verbeux) peut être utilisé pour délégué à l'utilisateur final le comportement souhaité pour les cas limites - qui parfois, peut nécessiter l'appel à
cmp(x,0)
.Je ne sais pas pourquoi il n'est pas intégré, mais j'ai quelques idées.
Le plus important,
copysign
est un sur-ensemble design
! L'appel decopysign
avec x=1 est la même que lasign
fonction. De sorte que vous pouvez simplement utilisercopysign
et oublier.Si vous êtes malade de passer deux arguments, vous pouvez mettre en œuvre
sign
de cette façon, et il sera toujours compatible avec la norme IEEE trucs mentionné par d'autres:Deuxièmement, généralement, quand vous voulez le signe de quelque chose, vous venez de finir multipliant avec une autre valeur. Et bien sûr, c'est fondamentalement ce
copysign
n'.Donc, au lieu de:
Il vous suffit de faire:
Et oui, je suis surpris que vous avez été à l'aide de Python pour les 7 ans et pense
cmp
pourrait être facilement enlevé et remplacé parsign
! Vous n'avez jamais mis en place une classe avec un__cmp__
méthode? Avez-vous jamais demandécmp
et spécifié un personnalisé comparateur de fonction?En résumé, j'ai trouvé moi-même de vouloir un
sign
fonction de trop, maiscopysign
avec le premier argument étant de 1 fonctionne très bien. Je suis en désaccord quesign
serait plus utile quecopysign
, comme je l'ai montré que c'est simplement un sous-ensemble de la même fonctionnalité.[int(copysign(1, zero)) for zero in (0, 0.0, -0.0)]
donne[1, 1, -1]
. Qui devrait avoir été[0, 0, 0]
selon en.wikipedia.org/wiki/Sign_functioncopysign(a,b)
retourne un avec le signe de b - b est la variable d'entrée, un est la valeur de normaliser avec b du signe. Dans ce cas, l'intervenant est illustrant que copysign(1,x) comme un remplacement pour le signe(x) échoue, car il renvoie 1 pour x=0, alors que le signe(0) permettrait d'évaluer à 0.cmp()
donnera les résultats souhaités, probablement pour presque tous les cas où quelqu'un serait en soucier:[cmp(zero, 0) for zero in (0, 0.0, -0.0, -4, 5)]
==>[0, 0, 0, -1, 1]
.s = sign(a) b = b * s
n'est pas équivalent àb = copysign(b, a)
! Il ne considère pas le signe de b. E. g. sia=b=-1
le premier code de retour 1, tandis que la seconde renvoie -1sign(0) == 1
. Cela ne semble pas comme il suit toute convention que j'en ai entendu parler."copysign" est défini par la norme IEEE 754, et une partie de la C99 de spécification. C'est pourquoi il est en Python. La fonction ne peut pas être pleinement mis en œuvre par l'abs(x) * signe(y) en raison de la façon dont il est censé s'occuper de valeurs NaN.
Qui fait copysign() plus utile, la fonction de signe().
De raisons particulières de l'IEEE signbit(x) n'est pas disponible en standard de Python, je ne sais pas. Je peux faire des hypothèses, mais il serait deviner.
Le module mathématique elle-même utilise signbit(1, x) pour vérifier si x est négatif ou non négatif. Pour la plupart des cas, de traiter avec les fonctions mathématiques qui semble plus utile que d'avoir un signe(x) qui retourne 1, 0, ou -1 car il y a moins de cas à considérer. Par exemple, le suivant est à partir de Python module math:
Là, vous pouvez clairement voir que copysign() est une fonction plus efficace que les trois-valeur de signe() fonction.
Vous avez écrit:
Cela signifie que vous ne savez pas que la cmp() est utilisé pour des choses en plus de numéros. cmp("Ceci", "Cela") ne peut pas être mis en œuvre avec un signe() fonction.
Modifier de rassembler mes réponses supplémentaires ailleurs:
Vous basez vos justifications sur la façon abs() et signe() sont souvent vus ensemble. Comme la bibliothèque C standard ne contient pas un " signe(x) la fonction de quelque sorte, je ne sais pas comment vous justifier votre point de vue. Il y a un abs(int) et fab(double) et fabsf(float) et fabsl(long), mais aucune mention de signe. Il est "copysign()" et "signbit ()", mais celles qui s'appliquent uniquement à la norme IEEE 754 numéros.
Avec des nombres complexes, ce qui serait signe(-3+4j) retour en Python, s'il devait être mis en œuvre? abs(-3+4j) retour 5.0. C'est un exemple clair de la façon dont l'abs() peut être utilisé dans des endroits où le signe() n'a aucun sens.
Supposons que sign(x) ont été ajoutés à Python, comme un complément de l'abs(x). Si 'x' est une instance d'une classe définie par l'utilisateur qui implémente l' __abs__(self) méthode abs(x) va appeler x.__abs__(). Afin de fonctionner correctement, d'poignée abs(x) de la même façon Python avoir un signe(x) logement.
C'est excessif pour un relativement inutiles fonction. D'ailleurs, pourquoi devrait-sign(x) existent et non négatif(x) et nonpositive(x) n'existent pas? Mon extrait de mathématiques Python module de mise en œuvre montre comment copybit(x, y) peut être utilisé pour mettre en œuvre non négatif(), qui d'un simple signe(x) ne peut pas faire.
Python doit de soutien ont un meilleur support pour la norme IEEE 754/C99 de fonction mathématique. Ajouter un signbit(x) de la fonction, ce qui permettrait de faire ce que vous voulez dans le cas de chars. Il ne serait pas travailler pour des entiers ou des nombres complexes, beaucoup moins de chaînes, et il n'aurait pas le nom que vous cherchez.
Vous demandez "pourquoi", et la réponse est "signe(x) n'est pas utile." Vous affirmer que c'est utile. Pourtant, vos commentaires montrent que vous ne connaissez pas suffisamment pour être en mesure de faire cette affirmation, ce qui signifie que vous auriez à montrer des preuves convaincantes de son besoin. Dire que NumPy met en œuvre, il n'est pas assez convaincant. Vous auriez besoin de montrer des cas de comment code existant serait améliorée avec une fonction de signe.
Et que, en dehors du champ d'application de StackOverflow. Prenez place à l'une des listes Python.
cmp()
nisign()
🙂Un autre liner de signe()
Si vous souhaitez retourner 0 pour x = 0:
cmp(x, 0)
est équivalent àsign
, etlambda x: cmp(x, 0)
est plus lisible que ce que vous suggérez.cmp(x, 0)
et savoir ce qu'il fait.-1 if x < 0 else 1
?sign = lambda x: -1 if x < 0 else 1
est 15% plus rapide. Même avecsign = lambda x: x and (-1 if x < 0 else 1)
.Depuis
cmp
a été supprimé, vous pouvez obtenir la même fonctionnalité avecIl travaille pour
float
,int
et mêmeFraction
. Dans le cas defloat
, avissign(float("nan"))
est zéro.Python n'exige pas que les comparaisons retourner un booléen, et ainsi de contraindre les comparaisons de bool() protège contre admissibles, mais rare de mise en œuvre:
L'essayer, où x est un nombre
La contrainte de bool() gère la possibilité que l'opérateur de comparaison n'a pas de retourner un booléen.
numpy a une fonction de signe, et vous donne un bonus d'autres fonctions. Donc:
Juste faire attention que le résultat est un numpy.float64:
Pour des choses comme le json, c'est important, en tant que json ne sais pas comment sérialiser numpy.float64 types. Dans ce cas, vous pourriez faire:
obtenir une float.
Oui une bonne
connexion()
fonction devrait être au moins dans le module math - comme c'est dans numpy. Parce que l'on a souvent besoin de ça pour les maths, le code orienté.Mais
math.copysign()
est également utile de façon indépendante.cmp()
etobj.__cmp__()
... ont généralement une grande importance indépendamment. Pas seulement pour les maths, le code orienté. Comparer/tri de n-uplets, les objets date, ...Le dev arguments à http://bugs.python.org/issue1640 concernant l'omission de
math.sign()
sont bizarre, parce que:-NaN
sign(nan) == nan
sans soucis (commeexp(nan)
)sign(-0.0) == sign(0.0) == 0
sans soucisign(-inf) == -1
sans souci-- comme il est dans numpy
Conforme à la définition de Wikipedia
La la définition sur Wikipédia lit:
Donc,
La définition de cette fonction exécute rapide et les rendements garantis des résultats corrects pour 0, 0.0, -0.0, 4 et 5 (voir les commentaires relatifs à ces réponses incorrectes).
Vous n'avez pas besoin d'un, vous pouvez simplement utiliser:
x / abs(x)
prend un peu plus de temps pour le chaînage deif/else
pour vérifier de quel côté de 0 la variable est sur, ou à l'aide de l'visqueux encore satisfaisantreturn (x > 0) - (x < 0)
soustrairebool
valeurs et retourner unint
True
etFalse
comme1
et0
, vous pouvez tout à fait faire cela et d'obtenir soit1
,0
, ou-1
.def sign(x): return (x > 0) - (x < 0)
ne renvoie pas unebool
, il va retourner unint
- si vous passez0
vous aurez0
dosEn Python 2, cmp() retourne un entier: il n'y a aucune exigence à ce que le résultat soit -1, 0, ou 1, le signe(x) n'est pas la même que la cmp(x,0).
En Python 3, cmp() a été retirée en faveur des riches comparaison. Pour cmp(), Python 3 suggère (https://docs.python.org/3/whatsnew/3.0.html):
qui est très bien pour les cmp(), mais encore ne peut pas être utilisé pour le signe() parce que les opérateurs de comparaison n'a pas besoin de retourner un booléen (https://docs.python.org/3/reference/datamodel.html#object.lt).
Pour faire face à cette possibilité, les résultats de la comparaison doit être contraints à faire des booléens:
Cela fonctionne pour n'importe quel type qui est totalement ordonnée (y compris les valeurs spéciales comme NaN ou infinis).
La raison "signe" n'est pas inclus, c'est que si nous avons inclus tous utiles one-liner dans la liste des fonctions intégrées, Python ne serait pas facile et pratique pour travailler avec plus.
Si vous utilisez cette fonction si souvent, alors pourquoi ne pas vous faire facteur vous-même? Ce n'est pas comme c'est dur à distance ou même fastidieux de le faire.
abs()
a été laissé de côté également.sign()
etabs()
sont souvent utilisés ensemble,sign()
est le plus utile des deux (OMI), et aucun n'est à distance difficile ou fastidieux à mettre en oeuvre (même si c'est source d'erreurs, de voir comment cette réponse se tromper: stackoverflow.com/questions/1986152/... )sign()
lui-même est rarement utile. Ce que vous faites la plupart du temps, c'est de prendre différents chemins de code basée sur le fait qu'une variable est positif ou négatif, et dans ce cas c'est plus lisible pour écrire la condition explicite.