Bagaimana saya bisa memformat desimal agar selalu menampilkan 2 tempat desimal?

237

Saya ingin menampilkan:

49 sebagai 49.00

dan:

54.9 sebagai 54.90

Terlepas dari panjang desimal atau apakah ada tempat desimal, saya ingin menampilkan a Decimaldengan 2 tempat desimal, dan saya ingin melakukannya dengan cara yang efisien. Tujuannya adalah untuk menampilkan nilai uang.

misalnya, 4898489.00

orokusaki
sumber
4
Anda membutuhkannya selama mungkin? Apa artinya? Anda dapat menambahkan nol di depan sampai kehabisan memori, tapi saya kira itu bukan yang Anda inginkan ...
Mark Byers
Saya kira itu mungkin berarti bahwa OP menggunakan desimal. Desimal dan tidak senang dengan presisi konteks desimal yang membatasi presisi hingga n digit seperti pada "n digit presisi dalam arti yang ketat" (mis. '123.456' menjadi Desimal ('1.2E + + 2 ')) dan bukan "n digit di bagian pecahan" (untuk Desimal (' 123,45 ')) ... Lihat jawaban saya untuk usaha membantu dengan ini. ;-)
Michał Marczyk
1
Ya, itu untuk nilai uang.
orokusaki

Jawaban:

105

Saya kira Anda mungkin menggunakan Decimal()objek dari decimalmodul? (Jika Anda membutuhkan tepat dua digit presisi di luar titik desimal dengan angka besar yang sewenang-wenang, Anda tentu harus, dan itulah yang disarankan judul pertanyaan Anda ...)

Jika demikian, bagian FAQ Desimal pada dokumen memiliki pasangan pertanyaan / jawaban yang mungkin berguna bagi Anda:

P. Dalam aplikasi titik tetap dengan dua tempat desimal, beberapa input memiliki banyak tempat dan perlu dibulatkan. Yang lain tidak seharusnya memiliki kelebihan angka dan perlu divalidasi. Metode apa yang harus digunakan?

A. Metode quantize () membulatkan ke sejumlah tempat desimal. Jika perangkap Inexact diatur, ini juga berguna untuk validasi:

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

Pertanyaan selanjutnya berbunyi

P. Setelah saya memiliki dua input tempat yang valid, bagaimana cara mempertahankan invarian di seluruh aplikasi?

Jika Anda memerlukan jawaban untuk itu (bersama dengan banyak informasi berguna lainnya), lihat bagian dokumen yang disebutkan di atas . Juga, jika Anda menjaga Decimalangka Anda dengan dua digit presisi di luar titik desimal (artinya sebanyak yang diperlukan untuk menjaga semua angka di sebelah kiri titik desimal dan dua di sebelah kanannya dan tidak lebih ...), kemudian mengonversinya menjadi string strakan bekerja dengan baik:

str(Decimal('10'))
# -> '10'
str(Decimal('10.00'))
# -> '10.00'
str(Decimal('10.000'))
# -> '10.000'
Michał Marczyk
sumber
2
Oh, lupa menyebutkan efisiensi dalam jawabannya ... tapi saya rasa saya bukan ahli. Saya tidak melihat alasan mengapa itu akan sangat tidak efisien untuk menjaga jumlah tetap "digit fraksional" di sekitar - meskipun setiap operasi yang dilakukan pada angka mungkin memerlukan operasi pembulatan pada hasil untuk membawanya sesuai dengan persyaratan ... Untuk Demi efisiensi, ini mungkin harus dilakukan sesering mungkin - seperti sesaat sebelum serialisasi / pencetakan untuk pengguna.
Michał Marczyk
517

Anda harus menggunakan spesifikasi format baru untuk menentukan bagaimana nilai Anda harus diwakili:

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

Dokumentasi bisa agak tumpul kadang-kadang, jadi saya merekomendasikan referensi berikut yang lebih mudah dibaca:

Python 3.6 memperkenalkan interpolasi string literal (juga dikenal sebagai f-string) jadi sekarang Anda dapat menulis di atas bahkan lebih ringkas sebagai:

>>> f'{pi:.2f}'
'3.14'
BiGeek
sumber
4
@Dogogan: Euh ... formatmengembalikan str, bukan float: print type({0:.2f}".format(pi))pengembalian <type 'str'>.
BioGeek
Ups. Kata kerja berlebihan pada kata return. Harap ubah secara mental ke prints.
Droogans
20
Jika Anda tidak ingin menggunakan penampung angka:"{:.2f}".format(pi)
Pengguna
Apa yang 0:dilakukan? Saya berasumsi .ini adalah bagian dari string python
information_interchange
135

Bagian Operasi Pemformatan String dari dokumentasi Python berisi jawaban yang Anda cari. Pendeknya:

"%0.2f" % (num,)

Beberapa contoh:

>>> "%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'
Travis Bradshaw
sumber
Tidak perlu untuk 0setelah %, dan tidak perlu bungkus numdalam tuple.
user238424
17
Sebenarnya, membungkus num dalam tuple adalah konvensi pengkodean untuk mencegah kesalahan mengetik bebek pada argumen selama pemformatan string. Dalam hal ini tidak memiliki efek dengan konversi float, tetapi mencegah kesalahan tipe yang tidak terduga ketika mengkonversi ke string. Pertimbangkan r = 1; "%s" % r; r = (1, 2); "%s" % rversus r = 1; "%s" % (r,); r = (1,2 ); "%s" % (r,). Dengan demikian, gaya pengkodean paling canggih dalam python menggunakan tuple tanpa syarat sekarang (dan Python 3 mencabut seluruh metode pemformatan string sebagai rawan kesalahan).
Travis Bradshaw
Juga, sebagai seorang pria dengan latar belakang matematika, notasi desimal "telanjang" itu jelek. 0 terkemuka tidak menyakiti apa pun dan terlihat lebih baik. :)
Travis Bradshaw
3
Secara estetika tidak berbeda. Yang terpenting, nilai 0 adalah nilai standarnya. Sama sekali tidak ada salahnya menyediakan default jika membuat kode yang menyenangkan secara estetika. Sangat menarik berapa banyak pengembang memilih untuk tidak (tidak bisa?) Membedakan antara kebenaran dan gaya. : /
Travis Bradshaw
32

Anda dapat menggunakan operator pemformatan string :

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

Saya tidak yakin apa yang Anda maksud dengan "efisien" - ini hampir pasti bukan hambatan aplikasi Anda. Jika program Anda berjalan lambat, buat profil dulu untuk menemukan hot spot, lalu optimalkan.

Adam Rosenfield
sumber
1
Saya pikir variabel yang diberi nama 'f' mungkin membingungkan beberapa orang. Lebih baik menyebutnya sesuatu yang lain untuk contoh seperti Travis di bawah ini.
Aleck Landgraf
28
>>> print "{:.2f}".format(1.123456)
1.12

Anda dapat mengubah 2dalam 2fke sejumlah titik desimal yang ingin ditampilkan.

EDIT:

Dari Python3.6, ini diterjemahkan menjadi:

>>> print(f"{1.1234:.2f}")
1.12
Aziz Alto
sumber
19

.format adalah cara yang lebih mudah dibaca untuk menangani pemformatan variabel:

'{:.{prec}f}'.format(26.034, prec=2)
Mayank Patel
sumber
18

Dalam python 3, cara melakukan ini adalah

'{:.2f}'.format(number)
Devin Ersoy
sumber
6

jika Anda memiliki beberapa parameter yang dapat Anda gunakan

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

Jika Anda menggunakan ini untuk mata uang, dan juga ingin nilai dipisahkan oleh ,Anda dapat menggunakan

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

misalnya:

currency_value = 1234.50

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

Ini sedikit kode yang saya tulis beberapa waktu lalu:

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
3kstc
sumber
0

Contoh cara termudah untuk menunjukkan kepada Anda bagaimana melakukannya adalah:

Kode:

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

Output: Jawaban yang benar: 88,64%

SHARON KERKETTA 1741050
sumber
-6

bagaimana dengan

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


print round(20.2564567 , 4)    >>>>>>>        20.2564
Mahmoud Hamdy
sumber