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.