Mise en forme des flotteurs en Python sans les zéros à droite
Comment puis-je formater un flotteur de sorte qu'il ne contient pas les zéros à droite? En d'autres termes, je veux la chaîne résultante à être aussi court que possible.
Par exemple:
3 -> "3"
3. -> "3"
3.0 -> "3"
3.1 -> "3.1"
3.14 -> "3.14"
3.140 -> "3.14"
- Cet exemple n'a pas de sens.
3.14 == 3.140
-- Ils sont le même nombre à virgule flottante. Pour cette question 3.140000 est le même nombre à virgule flottante. Le zéro n'existe pas dans la première place. - Je pense que le problème est en cours d'IMPRESSION, le nombre à virgule sans les zéros de fin, pas de l'équivalence de deux nombres.
- Dans ce cas, il n'y a pas de "superflu" de zéro.
%0.2f
et%0.3f
sont les deux formats requis pour produire les derniers numéros sur la gauche. Utilisation%0.2f
pour produire les deux derniers chiffres sur la droite. 3.0 -> "3"
est toujours valide d'un cas d'utilisation.print( '{:,g}'.format( X )
a fonctionné pour moi à la sortie de3
oùX = 6 / 2
et quandX = 5 / 2
j'ai eu une sortie de2.5
comme prévu.- vieille question, mais..
print("%s"%3.140)
vous donne ce que vous voulez. (J'ai ajouté une réponse vers le bas vers le bas ci-dessous...)
Vous devez vous connecter pour publier un commentaire.
Moi, je ferais
('%f' % x).rstrip('0').rstrip('.')
-- garanties point fixe sur la forme plutôt que la notation scientifique, etc etc. Ouais, pas aussi lisse et élégant que%g
, mais, ça marche (et je ne sais pas comment forcer%g
de ne jamais utiliser la notation scientifique;-).'%g' % x
utilisé pour, il y a sans doute plus agréable de la syntaxe. De Plus, vous pouvez maintenant sous-classestring.Formatter
de faire vos propres personnalisations.'%.2f' % -0.0001
vous laisse avec-0.00
et, finalement,-0
.'f' Fixed point. Displays the number as a fixed-point number. The default precision is 6.
que Vous auriez à utiliser '%0.7 f' dans la solution ci-dessus.'%0.15f'
est une mauvaise idée, parce que trucs bizarres commence à se produire.('%.2f' % -0.001).rstrip('0.')
quand il se réduit à'-'
print('In the middle {} and something else'.format('{:f}'.format(a).rstrip('0')))
rstrip
de commande. Utilisez simplement ceci à la place de la bande à la fois le point (.
) et tous les zéros à droite par la suite en une seule opération:('%f' % x).rstrip('.0')
Vous pouvez utiliser
%g
de réaliser ceci:ou, pour la version 2.6 de Python ou mieux:
De la docs pour
format
:g
causes (entre autres choses)'{0:...}'.format(value)
quand vous pourriez utiliserformat(value, '...')
? Ça évite d'avoir à analyser le spécificateur de format à partir d'un modèle de chaîne vide sinon.format(v, '2.5f')
prendre ~10% de plus que'{:2.5f}'.format(v)
. Même si elle n'a pas, j'ai tendance à utiliser lestr
méthode la forme, parce que quand j'ai besoin de le modifier, d'en ajouter d'autres valeurs, etc., il y a moins de changer. Bien sûr, en tant que de 3,6 nous avons f-chaînes pour la plupart des besoins. 🙂Qu'en essayant la méthode la plus simple et probablement le plus efficace?
La méthode normalize() supprime tous les plus à droite que les zéros à droite.
Travaille dans Python 2 et Python 3.
-- Mis à jour --
Le seul problème que @BobStein-VisiBone souligné, est que les nombres comme 10, 100, 1000... sera affiché dans la représentation exponentielle. Ceci peut être facilement fixé à l'aide de la fonction suivante à la place:
Decimal('10.0').normalize()
devient'1E+1'
Après avoir examiné les réponses à plusieurs questions similaires, ce qui semble être la meilleure solution pour moi:
Mon raisonnement:
%g
ne pas se débarrasser de la notation scientifique.15 décimales semble à éviter un comportement étrange et a beaucoup de précision pour mes besoins.
Je pourrais avoir utilisé
format(inputValue, '.15f').
au lieu de'%.15f' % inputValue
, mais qui est un peu plus lent (~30%).Je pourrais avoir utilisé
Decimal(inputValue).normalize()
, mais cela a quelques questions. Pour l'un, il est BEAUCOUP plus lent (~11x). J'ai aussi trouvé que, même si elle est assez grande précision, il souffre encore de la perte de précision due lors de l'utilisation denormalize()
.Plus important encore, je serais encore la conversion de
Decimal
à partir d'unfloat
qui peut faire de vous retrouver avec quelque chose d'autre que le numéro que vous avez mis là-dedans. Je pense queDecimal
fonctionne mieux lorsque le calcul reste dansDecimal
et laDecimal
est initialisé avec une chaîne.Je suis sûr que la question de précision de
Decimal.normalize()
peut être ajusté à ce qui est nécessaire à l'aide de paramètres de contexte, mais compte tenu de la déjà de la vitesse lente et n'ayant pas besoin de ridicule, de précision et le fait que je serais toujours la conversion à partir d'un flotteur et de perdre la précision de toute façon, je ne pense pas qu'il a été vaut la peine de poursuivre.Je ne suis pas concerné par la possible "-0" résultat depuis -0.0 est valide d'un nombre à virgule flottante, et qui serait probablement l'une des rares de toute façon, mais puisque vous ne mentionnez que vous voulez garder la chaîne la plus courte possible, vous pouvez toujours utiliser un conditionnel à très peu de vitesse supplémentaire des coûts.
floatToString(12345.6)
retourne'12345.600000000000364'
par exemple. La diminution de la 15 dans%.15f
d'un nombre inférieur de la résoudre dans cet exemple, mais cette valeur doit être diminué de plus et plus que le nombre devient plus grand. Il peut être calculée de manière dynamique basé sur le logarithme en base 10 du nombre, mais qui devient vite très compliqué.result = ('%15f' % val).rstrip('0').rstrip('.').lstrip(' ')
>>>12345.600000000000364 == 12345.6
True
Voici une solution qui a fonctionné pour moi. C'est un mélange de la solution par PolyMesh et l'utilisation de la nouvelle
.format()
la syntaxe.Sortie:
3.141
) comme le.2f
est codé en dur.Vous pouvez simplement utiliser le format() pour obtenir ceci:
format(3.140, '.10g')
où 10 est la précision que vous voulez.int(a) if a % 1 else a
?a if a % 1 else int(a)
est correct. La Question des besoins en sortie de chaîne , Donc j'ai juste ajoutéstr
a % 1
est truthy parce qu'il est non-nul. Je implicitement et perçue, à tort, commea % 1 == 0
.Alors que le formatage est probable que la plupart des Pythonic, voici une solution alternative à l'aide de la
more_itertools.rstrip
outil.Le nombre est converti en une chaîne de caractères, qui est dépouillé de caractères de fin qui répondent à un prédicat. La définition de la fonction
fmt
n'est pas nécessaire, mais il est utilisé ici pour tester affirmations, qui passent toutes. Remarque: il fonctionne sur la chaîne des entrées et accepte facultatif prédicats.Voir aussi les détails sur ce bibliothèque tierce,
more_itertools
.Si vous pouvez vivre avec 3. et 3.0 apparaissant comme "3.0", une approche très simple de ce droit-bandes des zéros de flotteur représentations:
(merci @ellimilial pour souligner les exceptions)
print("%s"%3.0)
n'.OP souhaitez supprimer superflouous zéros et de rendre la chaîne plus courte possible.
Je trouve le %g exponentielle mise en forme raccourcit la chaîne résultante pour les très grandes et très petites valeurs. Le problème vient de valeurs qui n'ont pas besoin de notation exponentielle, comme 128.0, qui n'est ni très grand ou très petit.
Ici est une façon de forme de nombres en chaînes courtes qui utilise %g de notation exponentielle seulement lorsque les Décimales.normaliser crée des chaînes de caractères qui sont trop longues. Cela pourrait ne pas être la solution la plus rapide (car il ne fait Décimal.normaliser)
Pour float vous pouvez utiliser ceci:
Tester:
Pour les Décimales voir la solution ici: https://stackoverflow.com/a/42668598/5917543
Utiliser %g avec une assez grande largeur, par exemple '%.99g'.
Il permet d'imprimer en notation à virgule fixe pour toute raisonnablement grand nombre.
EDIT: ça ne fonctionne pas
.99
, c'est la précision, pas de largeur; un peu utile, mais vous n'obtenez pas de définir le réel de la précision de cette façon (autre que la tronquant vous-même).Vous pouvez utiliser
max()
comme ceci:print(max(int(x), x))
x
est négatif.if x < 0: print(min(x), x)
else : print(max(x), x)
De manutention %f et vous devez les mettre
où:
.2f == .00 flotteurs.
Exemple:
print "Prix: %.2f" % prix[produit]
de sortie:
Prix: 1.50
Vous pouvez le faire dans la plupart des pythonic similaires:
python3:
"{:0.0f}".format(3.1)
est"3"
pas"3.1"