Wie kann ich eine Dezimalstelle so formatieren, dass immer 2 Dezimalstellen angezeigt werden?


237

Ich möchte anzeigen:

49 wie 49.00

und:

54.9 wie 54.90

Unabhängig von der Länge der Dezimalstelle oder ob es Dezimalstellen gibt, möchte ich eine Decimalmit 2 Dezimalstellen anzeigen , und ich möchte dies auf effiziente Weise tun. Der Zweck ist die Anzeige von Geldwerten.

z.B, 4898489.00


4
Sie brauchen es so lange wie möglich? Was bedeutet das? Sie könnten führende Nullen hinzufügen, bis Ihnen der Speicher ausgeht, aber ich vermute, dass Sie das nicht wollen ...
Mark Byers

Ich nehme an, es könnte bedeuten, dass das OP dezimal verwendet. Dezimal und unzufrieden mit der Genauigkeit des Dezimalkontexts, die die Genauigkeit auf n Ziffern begrenzt, wie in "n Ziffern der Genauigkeit im engeren Sinne" (z. B. wird '123.456' zu Dezimal ('1.2E +) 2 ')) und nicht "n Ziffern im Bruchteil" (für Dezimal (' 123.45 ')) ... Siehe meine Antwort für einen Versuch, dabei hilfreich zu sein. ;-)
Michał Marczyk

1
Ja, sie sind für Geldwerte.
Orokusaki

Antworten:


105

Ich nehme an, Sie verwenden wahrscheinlich die Decimal()Objekte aus dem decimalModul? (Wenn Sie genau zwei Stellen mit einer Genauigkeit hinter dem Dezimalpunkt mit beliebig großen Zahlen benötigen, sollten Sie dies auf jeden Fall tun, und der Titel Ihrer Frage legt dies nahe ...)

In diesem Fall enthält der Abschnitt " Dezimal-FAQ " der Dokumente ein Frage / Antwort-Paar, das für Sie hilfreich sein kann:

F. In einer Festkommaanwendung mit zwei Dezimalstellen haben einige Eingaben viele Stellen und müssen gerundet werden. Andere sollen keine überschüssigen Ziffern haben und müssen validiert werden. Welche Methoden sollten angewendet werden?

A. Die quantize () -Methode rundet auf eine feste Anzahl von Dezimalstellen. Wenn der Inexact-Trap gesetzt ist, ist er auch zur Validierung nützlich:

>>> TWOPLACES = Decimal(10) ** -2       # same as Decimal('0.01')
>>> # Round to two places
>>> Decimal('3.214').quantize(TWOPLACES)
Decimal('3.21')
>>> # Validate that a number does not exceed two places
>>> Decimal('3.21').quantize(TWOPLACES, context=Context(traps=[Inexact]))
Decimal('3.21')
>>> Decimal('3.214').quantize(TWOPLACES, context=Context(traps=[Inexact]))
Traceback (most recent call last):
   ...
Inexact: None

Die nächste Frage lautet

Frage: Wie kann ich diese Invariante in einer Anwendung beibehalten, wenn ich zwei gültige Eingaben habe?

Wenn Sie die Antwort darauf benötigen (zusammen mit vielen anderen nützlichen Informationen), lesen Sie den oben genannten Abschnitt der Dokumente . Wenn Sie Ihr Decimals mit zwei Stellen Genauigkeit über dem Dezimalpunkt halten (dh so viel Genauigkeit, wie erforderlich ist, um alle Stellen links vom Dezimalpunkt und zwei Stellen rechts davon und nicht mehr ...) zu halten, Wenn Sie sie dann in Strings mit konvertieren, strfunktioniert dies einwandfrei:

str(Decimal('10'))
# -> '10'
str(Decimal('10.00'))
# -> '10.00'
str(Decimal('10.000'))
# -> '10.000'

2
Oh, ich habe vergessen, die Effizienz in der Antwort zu erwähnen ... aber ich denke, ich bin sowieso kein Experte. Ich sehe keinen Grund, warum es besonders ineffizient wäre, eine feste Anzahl von "Bruchziffern" beizubehalten - obwohl alle Operationen, die an den Zahlen durchgeführt werden, möglicherweise eine Rundungsoperation für das Ergebnis erfordern könnten, um es an die Anforderungen anzupassen ... Für Aus Gründen der Effizienz sollte dies wahrscheinlich so selten wie möglich erfolgen - wie kurz vor der Serialisierung / dem Ausdruck für den Benutzer.
Michał Marczyk

516

Sie sollten die neuen Formatspezifikationen verwenden , um zu definieren, wie Ihr Wert dargestellt werden soll:

>>> from math import pi  # pi ~ 3.141592653589793
>>> '{0:.2f}'.format(pi)
'3.14'

Die Dokumentation kann manchmal etwas stumpf sein, daher empfehle ich die folgenden, leichter lesbaren Referenzen:

In Python 3.6 wurde die Literal-String-Interpolation (auch als F-Strings bezeichnet) eingeführt, sodass Sie die oben genannten Punkte noch prägnanter schreiben können als:

>>> f'{pi:.2f}'
'3.14'

4
@Droogans: Euh ... formatgibt a zurück str, nicht a float: gibt print type({0:.2f}".format(pi))zurück <type 'str'>.
BioGeek

Hoppla. Verbüberladung des Wortes return. Bitte ändern Sie das mental in prints.
Droogans

20
Wenn Sie den numerischen Platzhalter nicht verwenden möchten:"{:.2f}".format(pi)
Benutzer

Was macht das 0:? Ich nehme an, das .ist Teil der Python-Zeichenfolge
information_interchange

135

Der Abschnitt String-Formatierungsvorgänge in der Python-Dokumentation enthält die Antwort, nach der Sie suchen. Zusamenfassend:

"%0.2f" % (num,)

Einige Beispiele:

>>> "%0.2f" % 10
'10.00'
>>> "%0.2f" % 1000
'1000.00'
>>> "%0.2f" % 10.1
'10.10'
>>> "%0.2f" % 10.120
'10.12'
>>> "%0.2f" % 10.126
'10.13'

Es gibt keine Notwendigkeit für den 0nach dem %, und keine Notwendigkeit, Wrap numin ein tuple.
user238424

17
Tatsächlich ist das Umschließen von num in ein Tupel eine Codierungskonvention, um einen Enteneingabefehler bei Argumenten während der Zeichenfolgenformatierung zu verhindern. In diesem Fall hat dies bei einer Float-Konvertierung keine Auswirkung, verhindert jedoch einen unerwarteten Typfehler bei der Konvertierung in Zeichenfolgen. Betrachten Sie r = 1; "%s" % r; r = (1, 2); "%s" % rversus r = 1; "%s" % (r,); r = (1,2 ); "%s" % (r,). Daher verwenden die meisten ausgefeilten Codierungsstile in Python jetzt das bedingungslose Tupel (und Python 3 hat die gesamte Methode der Zeichenfolgenformatierung als fehleranfällig abgelehnt).
Travis Bradshaw

Als Mann mit mathematischem Hintergrund ist die "nackte" Dezimalschreibweise hässlich. Die führende 0 tut nichts weh und sieht besser aus. :)
Travis Bradshaw

3
Ästhetisch nicht anders. Am wichtigsten ist jedoch, dass die 0 ohnehin der Standardwert ist. Es schadet absolut nicht, die Standardeinstellung bereitzustellen, wenn dies zu einem ästhetisch ansprechenden Code führt. Es ist interessant, wie viele Entwickler sich dafür entscheiden, nicht zwischen Korrektheit und Stil zu unterscheiden (können nicht?). : /
Travis Bradshaw

32

Sie können den Zeichenfolgenformatierungsoperator folgendermaßen verwenden :

num = 49
x = "%.2f" % num  # x is now the string "49.00"

Ich bin mir nicht sicher, was Sie unter "effizient" verstehen - dies ist mit ziemlicher Sicherheit nicht der Engpass Ihrer Anwendung. Wenn Ihr Programm langsam läuft, profilieren Sie es zuerst, um die Hotspots zu finden, und optimieren Sie diese dann.


1
Ich denke, die Variable mit dem Namen 'f' könnte einige Leute verwirren. Nennen Sie es besser etwas anderes für ein Beispiel wie Travis unten.
Aleck Landgraf

28
>>> print "{:.2f}".format(1.123456)
1.12

Sie können 2in 2feine beliebige Anzahl von Dezimalstellen wechseln , die Sie anzeigen möchten.

BEARBEITEN:

Aus bedeutet Python3.6dies:

>>> print(f"{1.1234:.2f}")
1.12

19

.format ist eine besser lesbare Methode zur Handhabung der Variablenformatierung:

'{:.{prec}f}'.format(26.034, prec=2)


6

Wenn Sie mehrere Parameter haben, können Sie verwenden

 print('some string {0:.2f} & {1:.2f}'.format(1.1234,2.345))
 >>> some string 1.12 & 2.35

3

Wenn Sie dies für die Währung verwenden und möchten, dass der Wert durch ,'s getrennt wird, können Sie ihn verwenden

$ {:,.f2}.format(currency_value).

z.B:

currency_value = 1234.50

$ {:,.f2}.format(currency_value) --> $ 1,234.50

Hier ist ein bisschen Code, den ich vor einiger Zeit geschrieben habe:

print("> At the end of year " + year_string + " total paid is \t$ {:,.2f}".format(total_paid))

> At the end of year   1  total paid is         $ 43,806.36
> At the end of year   2  total paid is         $ 87,612.72
> At the end of year   3  total paid is         $ 131,419.08
> At the end of year   4  total paid is         $ 175,225.44
> At the end of year   5  total paid is         $ 219,031.80   <-- Note .80 and not .8
> At the end of year   6  total paid is         $ 262,838.16
> At the end of year   7  total paid is         $ 306,644.52
> At the end of year   8  total paid is         $ 350,450.88
> At the end of year   9  total paid is         $ 394,257.24
> At the end of year  10  total paid is         $ 438,063.60   <-- Note .60 and not .6
> At the end of year  11  total paid is         $ 481,869.96
> At the end of year  12  total paid is         $ 525,676.32
> At the end of year  13  total paid is         $ 569,482.68
> At the end of year  14  total paid is         $ 613,289.04
> At the end of year  15  total paid is         $ 657,095.40   <-- Note .40 and not .4  
> At the end of year  16  total paid is         $ 700,901.76
> At the end of year  17  total paid is         $ 744,708.12
> At the end of year  18  total paid is         $ 788,514.48
> At the end of year  19  total paid is         $ 832,320.84
> At the end of year  20  total paid is         $ 876,127.20   <-- Note .20 and not .2

0

Das einfachste Beispiel, um Ihnen zu zeigen, wie das geht, ist:

Code:

>>> points = 19.5 >>> total = 22 >>>'Correct answers: {:.2%}'.format(points/total) `

Ausgabe: Richtige Antworten: 88,64%


-6

wie wäre es mit

print round(20.2564567 , 2)    >>>>>>>        20.25


print round(20.2564567 , 4)    >>>>>>>        20.2564
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.