Jak sformatować ułamek dziesiętny, aby zawsze wyświetlać 2 miejsca po przecinku?


237

Chcę wyświetlić:

49 tak jak 49.00

i:

54.9 tak jak 54.90

Bez względu na długość miejsca po przecinku lub czy są jakieś miejsca po przecinku, chciałbym wyświetlić Decimalz 2 miejscami po przecinku i chciałbym to zrobić w efektywny sposób. Celem jest wyświetlanie wartości pieniężnych.

na przykład, 4898489.00


4
Potrzebujesz być tak długi, jak to możliwe? Co to znaczy? Możesz dodawać początkowe zera, dopóki nie zabraknie ci pamięci, ale podejrzewam, że nie tego chcesz ...
Mark Byers

Podejrzewam, że może to oznaczać, że OP używa dziesiętnej.Decymalnej i jest niezadowolony z precyzji kontekstu dziesiętnego, która ogranicza precyzję do n cyfr, jak w „n cyfrach ścisłości w ścisłym tego słowa znaczeniu” (np. „123.456” staje się dziesiętne („1.2E + 2 ')), a nie „n cyfr w części ułamkowej” (dla Dziesiętnej („123,45”)) ... Zobacz moją odpowiedź, aby spróbować w tym pomóc. ;-)
Michał Marczyk

1
Tak, są dla wartości pieniężnych.
orokusaki,

Odpowiedzi:


105

Przypuszczam, że prawdopodobnie używasz Decimal()obiektów z decimalmodułu? (Jeśli potrzebujesz dokładnie dwóch cyfr precyzji poza kropką dziesiętną z dowolnie dużymi liczbami, zdecydowanie powinieneś być, i tak sugeruje tytuł pytania ...)

Jeśli tak, sekcja Dziesiętne FAQ w dokumentach zawiera parę pytań / odpowiedzi, która może Ci się przydać:

P: W aplikacji ze stałymi punktami z dwoma miejscami dziesiętnymi niektóre dane wejściowe mają wiele miejsc i należy je zaokrąglić. Inne nie powinny mieć nadmiaru cyfr i muszą zostać zatwierdzone. Jakie metody należy zastosować?

A. Metoda quantize () zaokrągla do stałej liczby miejsc po przecinku. Jeśli ustawiono pułapkę Inexact, jest ona również przydatna do sprawdzania poprawności:

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

Następne pytanie brzmi

P: Kiedy mam prawidłowe dwa dane wejściowe miejsca, w jaki sposób mogę zachować ten niezmienny w całej aplikacji?

Jeśli potrzebujesz odpowiedzi na to pytanie (wraz z mnóstwem innych przydatnych informacji), zapoznaj się z wyżej wymienioną sekcją dokumentów . Ponadto, jeśli trzymasz Decimals z dwiema cyframi precyzji poza przecinkiem dziesiętnym (co oznacza tyle precyzji, ile jest konieczne, aby wszystkie cyfry były na lewo od przecinka dziesiętnego i dwie na prawo od niego i nie więcej ...), następnie przekonwertowanie ich na ciągi znaków strbędzie działało dobrze:

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

2
Och, zapomniałem wspomnieć o wydajności w odpowiedzi ... ale chyba i tak nie jestem ekspertem. Nie widzę powodu, dla którego szczególnie nieefektywne byłoby utrzymywanie stałej liczby „cyfr ułamkowych” - chociaż wszelkie operacje na liczbach mogą wymagać operacji zaokrąglania wyniku w celu dostosowania go do wymagań ... ze względu na wydajność, powinno to być prawdopodobnie wykonywane tak rzadko, jak to możliwe - na przykład tuż przed serializacją / wydrukowaniem dla użytkownika.
Michał Marczyk

517

Należy użyć specyfikacji nowego formatu, aby zdefiniować sposób reprezentacji wartości:

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

Czasami dokumentacja może być nieco tępa, dlatego polecam następujące, łatwiejsze do odczytania odniesienia:

W Pythonie 3.6 wprowadzono literalną interpolację ciągów znaków (znaną również jako ciągi f), dzięki czemu można teraz napisać powyższe jeszcze bardziej zwięzłe:

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

4
@Droogans: Euh ... formatzwraca a str, a nie float: print type({0:.2f}".format(pi))zwraca <type 'str'>.
BioGeek,

Ups Przeciążenie czasownika w słowie return. Proszę, mentalnie zmień to na prints.
Droogany

20
Jeśli nie chcesz używać liczbowego symbolu zastępczego:"{:.2f}".format(pi)
Użytkownik

Czego 0:zrobić? Zakładam, że .jest częścią ciągu python
information_interchange

135

Sekcja Operacje formatowania łańcucha w dokumentacji Pythona zawiera odpowiedź, której szukasz. W skrócie:

"%0.2f" % (num,)

Kilka przykładów:

>>> "%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'

Nie ma potrzeby 0późniejszego %i nie trzeba owijać numw tuple.
user238424

17
W rzeczywistości zawijanie liczby w krotkę to konwencja kodowania, która zapobiega błędom podczas wpisywania argumentów podczas formatowania łańcucha znaków. W tym przypadku nie ma to żadnego wpływu na konwersję zmiennoprzecinkową, ale zapobiega nieoczekiwanemu błędowi typu podczas konwersji na ciągi. Rozważ r = 1; "%s" % r; r = (1, 2); "%s" % rkontra r = 1; "%s" % (r,); r = (1,2 ); "%s" % (r,). Jako takie, najbardziej wyrafinowane style kodowania w Pythonie wykorzystują teraz bezwarunkową krotkę (a Python 3 przestarzał całą metodę formatowania ciągów jako podatną na błędy).
Travis Bradshaw,

Ponadto, jako facet z matematyki, „naga” notacja dziesiętna jest brzydka. Pierwsze 0 nic nie boli i wygląda lepiej. :)
Travis Bradshaw,

3
Estetycznie nie inaczej. Co najważniejsze, 0 jest zresztą wartością domyślną. Zapewnienie domyślnego ustawienia nie jest absolutnie szkodliwe, jeśli stanowi estetyczny kod. Ciekawe, ilu programistów decyduje się (nie?) Rozróżniać między poprawnością a stylem. : /
Travis Bradshaw,

32

Możesz użyć operatora formatowania łańcucha w następujący sposób:

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

Nie jestem pewien, co rozumiesz przez „wydajny” - prawie na pewno nie jest to wąskie gardło twojej aplikacji. Jeśli twój program działa wolno, profiluj go najpierw, aby znaleźć gorące punkty, a następnie zoptymalizuj je.


1
Myślę, że zmienna o nazwie „f” może dezorientować niektórych ludzi. Lepiej nazwać to inaczej, na przykład poniżej Travis.
Aleck Landgraf,

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

Można zmienić 2w 2fdowolnej liczbie miejsc po przecinku, które chcesz pokazać.

EDYTOWAĆ:

Z Python3.6ta przekłada się na:

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

19

.format jest bardziej czytelnym sposobem obsługi formatowania zmiennych:

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


6

jeśli masz wiele parametrów, których możesz użyć

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

3

Jeśli używasz tego do waluty, a także chcesz, aby wartość była oddzielona przez ,, możesz użyć

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

na przykład:

currency_value = 1234.50

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

Oto trochę kodu, który napisałem jakiś czas temu:

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

Najprostszym przykładem pokazującym, jak to zrobić, jest:

Kod :

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

Wynik: prawidłowe odpowiedzi: 88,64%


-6

co powiesz na

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


print round(20.2564567 , 4)    >>>>>>>        20.2564
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.