Formatierung Schwimmer in Python ohne nachfolgende Nullen
Wie kann ich das format ein float, so dass es nicht enthalten nachfolgende Nullen? In anderen Worten, ich möchte die resultierende Zeichenfolge so kurz wie möglich.
Beispiel:
3 -> "3"
3. -> "3"
3.0 -> "3"
3.1 -> "3.1"
3.14 -> "3.14"
3.140 -> "3.14"
- Das Beispiel macht keinen Sinn.
3.14 == 3.140
- Sie sind die gleiche floating-point-Zahl. Für diese Angelegenheit 3.140000 ist die gleiche floating-point-Zahl. Die null existiert nicht in den ersten Platz. - Ich denke, das Problem ist der DRUCK der float-Zahl ohne Nullen, nicht die tatsächliche äquivalenz der beiden zahlen.
- In dem Fall, es gibt keine "überflüssigen" null.
%0.2f
und%0.3f
sind die beiden Formate zu produzieren, die letzten zahlen auf der linken Seite. Verwenden%0.2f
zu produzieren, die letzten beiden zahlen auf der rechten Seite. 3.0 -> "3"
ist immer noch ein Gültiger Anwendungsfall.print( '{:,g}'.format( X )
bei mir funktioniert die Ausgabe3
woX = 6 / 2
und wennX = 5 / 2
bekam ich eine Ausgabe von2.5
als erwartet.- alte Frage, aber..
print("%s"%3.140)
gibt Ihnen, was Sie wollen. (Ich fügte hinzu, eine Antwort unten siehe unten...)
Du musst angemeldet sein, um einen Kommentar abzugeben.
Mir, das ich tun würde
('%f' % x).rstrip('0').rstrip('.')
-- garantiert fixed-point-Formatierung statt der wissenschaftlichen notation, etc etc. Ja, nicht so glatt und elegant als%g
, aber es funktioniert (und ich weiß nicht, wie zu zwingen%g
nie in wissenschaftlicher Schreibweise;-).'%g' % x
verwendet, es hat nur ein wohl schönere syntax. Plus, können Sie jetzt eine Unterklassestring.Formatter
zu tun, Ihre eigenen Anpassungen.'%.2f' % -0.0001
verlassen Sie mit-0.00
und letztlich-0
.'f' Fixed point. Displays the number as a fixed-point number. The default precision is 6.
Sie würden für die Verwendung von '%0.7 f " in der obigen Lösung.'%0.15f'
ist eine schlechte Idee, weil weird stuff beginnt zu geschehen.('%.2f' % -0.001).rstrip('0.')
wenn es reduziert sich auf'-'
print('In the middle {} and something else'.format('{:f}'.format(a).rstrip('0')))
rstrip
Befehl. Verwenden Sie einfach diese statt der Streifen sowohl den Punkt (.
) und alle nachgestellten Nullen Sie danach in Betrieb:('%f' % x).rstrip('.0')
Könnten Sie
%g
um dies zu erreichen:oder, für Python 2.6 oder besser:
Aus der docs für
format
:g
Ursachen (unter anderem)'{0:...}'.format(value)
wenn Sie könnte verwendenformat(value, '...')
? Das verhindert, dass analysiert wird der Formatbezeichner aus einer Vorlage-Zeichenfolge, die ist sonst leer.format(v, '2.5f')
nehmen ~10% länger als'{:2.5f}'.format(v)
. Auch wenn Sie es nicht Tat, ich Neige dazu, verwenden Sie diestr
Methode bilden, weil, wenn ich brauche, um es zu optimieren, zusätzliche Werte, etc., es ist weniger zu ändern. Natürlich, wie von 3.6 haben wir die f-Saiten für die meisten Zwecke. 🙂Was zu versuchen die einfachste und wahrscheinlich effektivste Ansatz?
Die Methode normalize() entfernt alle niedrigstwertigen Nullen.
Arbeitet in Python 2 und Python 3.
-- Aktualisiert --
Nur das problem ist, wie @BobStein-VisiBone darauf hingewiesen wird, dass zahlen wie 10, 100, 1000... werden angezeigt, die in exponentieller Darstellung. Dies kann leicht behoben mit der folgenden Funktion statt:
Decimal('10.0').normalize()
wird'1E+1'
Nachdem ich über Antworten auf mehrere ähnliche Fragen, scheint dies die beste Lösung für mich:
Meine überlegung:
%g
nicht loszuwerden, die wissenschaftliche notation.15 Dezimalstellen scheint zu vermeiden, seltsames Verhalten und hat viel Präzision für meine Bedürfnisse.
Hätte ich
format(inputValue, '.15f').
statt'%.15f' % inputValue
, aber das ist etwas langsamer (~30%).Hätte ich
Decimal(inputValue).normalize()
, aber dies hat ein paar Probleme. Zum einen, es ist VIEL langsamer (~11x). Ich fand auch, dass, obwohl es hat ziemlich große Präzision, es leidet immer noch unter Präzisions-Verlust bei der Verwendung vonnormalize()
.Allem würde ich immer noch auf die Umwandlung zu
Decimal
aus einerfloat
was machen Sie am Ende mit etwas anderes als die Nummer, die Sie in es gesetzt. Ich denkeDecimal
funktioniert am besten, wenn das arithmetische bleibt inDecimal
und dieDecimal
initialisiert ein string.Ich bin sicher, dass die Präzision Ausgabe von
Decimal.normalize()
eingestellt werden kann, was notwendig ist, mit Kontext-Einstellungen, aber in Anbetracht der bereits langsame Geschwindigkeit und nicht brauchen lächerlich Präzision und die Tatsache, dass ich immer noch die Konvertierung von float und verlieren Genauigkeit wie auch immer, ich nicht denke, dass es Wert war, verfolgt.Ich bin nicht besorgt über die möglichen "-0" Ergebnis seit -0.0 ist eine gültige floating point Zahl, und es wäre wahrscheinlich ein Seltenes Ereignis in jedem Fall, aber da hat man noch erwähnen, Sie wollen, halten Sie die Zeichenfolge Ergebnis so kurz wie möglich, Sie können immer mit einer extra-bedingt sehr wenig zusätzliche Geschwindigkeit Kosten.
floatToString(12345.6)
zurück'12345.600000000000364'
zum Beispiel. Eine Verringerung der 15 in%.15f
zu einer niedrigeren Nummer betätigt, löst es in diesem Beispiel, aber dieser Wert muss verringert werden, mehr und mehr, als die Zahl größer wird. Es könnte sein, dynamisch berechnet auf der Basis des log-Basis 10 von der Zahl, aber das wird schnell sehr kompliziert.result = ('%15f' % val).rstrip('0').rstrip('.').lstrip(' ')
>>>12345.600000000000364 == 12345.6
True
Hier ist eine Lösung, die für mich gearbeitet. Es ist eine Mischung der Lösung von PolyMesh und Nutzung der neuen
.format()
syntax.Ausgabe:
3.141
) als.2f
ist hart codiert.Können Sie einfach format() um dies zu erreichen:
format(3.140, '.10g')
wobei 10 die Präzision, die Sie wollen.int(a) if a % 1 else a
?a if a % 1 else int(a)
korrekt ist. Frage muss die Ausgabe in string , So dass ich nur Hinzugefügtstr
a % 1
ist truthy, weil es nicht null ist. Ich implizit und fälschlicherweise denken, esa % 1 == 0
.Während der Formatierung ist wahrscheinlich, dass die meisten Pythonic way, hier ist eine Alternative Lösung, mit der
more_itertools.rstrip
tool.Die Zahl wird in eine Zeichenfolge konvertiert, die beraubt nachfolgende Zeichen erfüllen ein Prädikat. Die definition der Funktion
fmt
ist nicht erforderlich, aber es wird hier verwendet, um test-assertions, die alle erfolgreich waren. Hinweis: es funktioniert auf string-Eingänge und akzeptiert optionale Prädikate.Siehe auch details auf dieser Drittanbieter-Bibliothek
more_itertools
.Wenn Sie Leben können mit 3. und 3.0 erscheinen als "3.0", ein sehr einfacher Ansatz, der rechts-Streifen Nullen von float-Darstellungen:
(danke @ellimilial für den Hinweis auf die Ausnahmen)
print("%s"%3.0)
tut.OP entfernen möchten superflouous Nullen und stellen Sie die resultierende Zeichenfolge so kurz wie möglich.
Ich finde die %g exponentiellen Formatierung verkürzt den entsprechenden string für sehr große und sehr kleine Werte. Das problem kommt für Werte, die nicht brauchen, exponential-notation, wie 128.0, die weder sehr groß oder sehr klein.
Hier ist eine Möglichkeit zum formatieren von zahlen als kurze Zeichenfolgen, die verwendet %g Exponentialschreibweise nur wenn Nachkommastellen.normalisieren schafft Zeichenfolgen, die zu lang sind. Das ist vielleicht nicht die Schnellste Lösung (da es nicht Dezimal.normalisieren)
Für float-Sie können diese:
Test:
Dezimal-Lösung finden Sie hier: https://stackoverflow.com/a/42668598/5917543
Benutzen Sie %g mit groß genug Breite, zum Beispiel '%.99g'.
Es wird gedruckt in fixed-point notation für jede halbwegs große Nummer.
EDIT: es funktioniert nicht
.99
ist die Präzision, nicht Breite; irgendwie nützlich, aber Sie nicht bekommen, um die tatsächliche Genauigkeit dieser Art (andere als mit dem abschneiden von selbst).Können Sie
max()
wie diese:print(max(int(x), x))
x
negativ ist.if x < 0: print(min(x), x)
else : print(max(x), x)
Umgang mit "%f", und Sie sollten
wo:
.2f == .00 schwimmt.
Beispiel:
print "Preis: %.2f" % Preise[Produkt]
Ausgabe:
Preis: 1.50
Können Sie erreichen, dass in den meisten pythonic way so:
Python ist3:
"{:0.0f}".format(3.1)
ist"3"
nicht"3.1"