Pemformatan mata uang dengan Python

156

Saya ingin memformat angka seperti 188518982.18 menjadi £ 188.518.982,18 menggunakan Python.

Bagaimana saya bisa melakukan ini?

RailsSon
sumber
Anda membuat poin yang sangat baik dalam komentar di bawah ini, @RailsSon: Anda ingin mencetak £ untuk menampilkan mata uang tertentu, tetapi gunakan tampilan itu menggunakan ekspresi Jepang untuk angka keuangan. Saya merasa aneh bahwa permintaan Anda belum diimplementasikan dalam bahasa dengan memisahkan penggunaan localemodul nilai mata uang dan properti tampilan mata uang itu.
Droogans

Jawaban:

212

Lihat modul lokal .

Ini memformat mata uang (dan tanggal).

>>> import locale
>>> locale.setlocale( locale.LC_ALL, '' )
'English_United States.1252'
>>> locale.currency( 188518982.18 )
'$188518982.18'
>>> locale.currency( 188518982.18, grouping=True )
'$188,518,982.18'
S.Lott
sumber
15
Bagaimana saya memformat mata uang non-asli dengan benar, Katakan saya menunjukkan biaya dalam GB pound untuk laporan bahasa Jepang?
SingleNegationElimination
2
@TokenMacGuy: Itu Pertanyaan Trik. Laporan Jepang berarti koma Jepang dan aturan tempat desimal tetapi simbol GB Pound mata uang - tidak didukung sepele oleh Lokal. Anda harus membuat definisi lokal yang disesuaikan.
S.Lott
jika angka pemberi negatif mengembalikan nilai antara "()" mengapa?
panchicore
6
Ini masih tidak berhasil untuk saya, tetapi saya mengubahnya locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')dan bekerja dengan sempurna!
Furbeenator
2
@panchicore, notasi untuk bilangan negatif sebagaimana dilambangkan oleh tanda kurung adalah praktik umum dalam dunia akuntansi. Cobalah di oocalc atau excel, dan format angka ke tipe akuntansi.
Droogans
94

Baru di 2.7

>>> '{:20,.2f}'.format(18446744073709551616.0)
'18,446,744,073,709,551,616.00'

http://docs.python.org/dev/whatsnew/2.7.html#pep-0378

nate c
sumber
6
Itu rapi tetapi tidak benar-benar menjawab pertanyaan, karena solusi yang diminta akan menyertakan simbol mata uang, dan Anda juga mengkodekan jumlah digit setelah desimal, yang khusus lokal. Ada banyak alasan lain untuk menggunakan jawaban lokal yang diterima jika Anda tidak hanya ingin penempatan koma.
mrooney
6
@ mooney Ada juga banyak alasan untuk tidak menggunakan jawaban lokal yang diterima, seperti tidak mengimpor seluruh modul.
Josh
1
@Josh, "dari mata uang impor lokal".
Andrew H
5
@mrooney: Anda hanya dapat melakukan: '$ {: 0, .2f}'. (184467616.1), dan sekarang Anda memiliki simbol
triunenature
@triunenature yang $ 123,456.78terkadang menghasilkan . Sunting: penurunan harga mengeluarkan ruang ekstra, berpura-pura ada lebih banyak antara $ dan angka
CyberJacob
48

Tidak yakin mengapa itu tidak disebutkan lebih online (atau di utas ini), tetapi paket Babel (dan utilitas Django) dari orang-orang Edgewall luar biasa untuk pemformatan mata uang (dan banyak tugas i18n lainnya). Itu bagus karena tidak menderita dari keharusan untuk melakukan semuanya secara global seperti modul lokal Python inti.

Contoh yang OP berikan adalah:

>>> import babel.numbers
>>> import decimal
>>> babel.numbers.format_currency( decimal.Decimal( "188518982.18" ), "GBP" )
£188,518,982.18
Glenc
sumber
2
Catatan yang sangat terlambat: Menguji ini, tampaknya tidak memformat mata uang secara cerdas, karena hanya menempel simbol yang sesuai sebelum jumlahnya (diformat dalam apa yang tampaknya menjadi lokasi yang telah Anda tetapkan, yang masuk akal), terlepas dari apakah mata uang itu benar-benar menggunakan simbolnya sebagai awalan.
kungphu
@ Kungphu Apa maksudmu? Lihat babel.pocoo.org/en/latest/api/…
Julian
1
@Julian Sepertinya localeargumen yang format_currencydapat digunakan untuk mengatasi hal ini, tapi entah itu tidak ada dalam dokumen empat tahun yang lalu (ketika saya menulis komentar itu) atau saya baru saja menguji kode jawaban ini apa adanya tanpa memeriksa dokumen.
kungphu
1
@kungphu Gotcha. Saya pasti tidak memperhatikan usia posting ini kemarin. Perubahan dokumentasi / fungsi tampaknya sangat mungkin. Bersulang!
Julian
32

Ini adalah pos kuno, tetapi saya baru saja mengimplementasikan solusi berikut ini yang:

  • Tidak memerlukan modul eksternal
  • Tidak perlu membuat fungsi baru
  • Dapat dilakukan in-line
  • Menangani banyak variabel
  • Menangani jumlah dolar negatif

Kode:

num1 = 4153.53
num2 = -23159.398598

print 'This: ${:0,.0f} and this: ${:0,.2f}'.format(num1, num2).replace('$-','-$')

Keluaran:

This: $4,154 and this: -$23,159.40

Dan untuk poster asli, jelas, hanya beralih $untuk£

elPastor
sumber
format saya memerlukan beberapa penyesuaian, tetapi tidak apa-apa karena saya dapat melakukannya dengan solusi ini.
DonkeyKong
10
Ide keren! Dengan Python 3.6 dan f-string, itu terlihat lebih indah:print(f'Value is: ${value:,.2f}'.replace('$-', '-$'))
Timo Saloranta
16

Pengaturan lokal saya sepertinya tidak lengkap, jadi saya juga melihat melampaui jawaban SO ini dan menemukan:

http://docs.python.org/library/decimal.html#recipes

OS-independen

Hanya ingin berbagi di sini.

pengguna37986
sumber
Tapi di mana kita menyebutnya def moneyfmt(value, places=2, curr='', sep=',', dp='.', pos='', neg='-', trailneg='')?
Roel
9

Jika Anda menggunakan OSX dan belum menetapkan pengaturan modul lokal Anda, jawaban pertama ini tidak berfungsi Anda akan menerima kesalahan berikut:

Traceback (most recent call last):File "<stdin>", line 1, in <module> File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/locale.py", line 221, in currency
raise ValueError("Currency formatting is not possible using "ValueError: Currency formatting is not possible using the 'C' locale.

Untuk mengatasinya, Anda harus menggunakan yang berikut ini:

locale.setlocale(locale.LC_ALL, 'en_US')
simoes
sumber
2
locale.setlocale (locale.LC_ALL, 'en_US.UTF-8') cocok untuk saya
alexblum
9

"{:0,.2f}".format(float(your_numeric_value))dalam Python 3 melakukan pekerjaan; itu memberikan sesuatu seperti salah satu dari baris berikut:

10,938.29
10,899.00
10,898.99
2,328.99
Eugene Gr. Philippov
sumber
6

Jika saya jadi Anda, saya akan menggunakan BABEL: http://babel.pocoo.org/en/latest/index.html

from babel.numbers import format_decimal


format_decimal(188518982.18, locale='en_US')
Carlos
sumber
1
Modul python locale tidak bekerja untuk saya (apa pun lokal yang saya atur, ia mengeluh) tetapi membutuhkan babel dan menggunakan fungsi ini bagus. Layak untuk dilihat dalam API API karena ada lebih banyak parameter dan fungsi yang lebih bermanfaat (seperti untuk mata uang:) format_currency.
Daniel W.
3

Oh, itu binatang yang menarik.

Saya telah menghabiskan banyak waktu untuk memperbaiki hal itu, ada tiga masalah utama yang berbeda dari lokal ke lokal: - simbol dan arah mata uang - ribuan pemisah - titik desimal

Saya sudah menulis implementasi saya sendiri yang agak ekstensif tentang ini yang merupakan bagian dari kerangka python kiwi, lihat LGPL: sumber ed di sini:

http://svn.async.com.br/cgi-bin/viewvc.cgi/kiwi/trunk/kiwi/currency.py?view=markup

Kode ini sedikit spesifik untuk Linux / Glibc, tetapi seharusnya tidak terlalu sulit untuk diadopsi ke windows atau unix lainnya.

Setelah Anda menginstalnya, Anda dapat melakukan hal berikut:

>>> from kiwi.datatypes import currency
>>> v = currency('10.5').format()

Yang kemudian akan memberi Anda:

'$10.50'

atau

'10,50 kr'

Tergantung pada lokal yang saat ini dipilih.

Poin utama dari postingan ini adalah bahwa ini akan bekerja dengan versi python yang lebih lama. locale.currency diperkenalkan dalam python 2.5.

Johan Dahlin
sumber
Apakah ada kelebihan dibandingkan locale.currency ()?
Ali Afshar
@AliAfshar: Satu keuntungan adalah sebagai 10,50 krganti kr 10,50.
user2394284
2

#cetak variabel 'Total:' dalam format yang terlihat seperti ini '9,348.237'

print ('Total:',   '{:7,.3f}'.format(zum1))

di mana '{: 7, .3f}' adalah jumlah spasi untuk memformat angka dalam kasus ini adalah satu juta dengan 3 angka desimal. Kemudian Anda menambahkan '.format (zum1). Zum1 adalah variabel tha yang memiliki jumlah besar untuk jumlah semua angka dalam program khusus saya. Variabel bisa berupa apa saja yang Anda putuskan untuk digunakan.

Marie
sumber
1

Terinspirasi oleh kode di atas: D

def money_format(value):
value = str(value).split('.')
money = ''
count = 1

for digit in value[0][::-1]:
    if count != 3:
        money += digit
        count += 1
    else:
        money += f'{digit},'
        count = 1

if len(value) == 1:
    money = ('$' + money[::-1]).replace('$-','-$')
else:
    money = ('$' + money[::-1] + '.' + value[1]).replace('$-','-$')

return money
Elmer Gonzalez
sumber
0

Saya datang untuk melihat hal yang sama dan menemukan python-money belum benar-benar menggunakannya, tetapi mungkin campuran keduanya akan baik

James Brooks
sumber
0

Sebuah lambda untuk menghitungnya di dalam fungsi, dengan bantuan dari jawaban @ Nate

converter = lambda amount, currency: "%s%s%s" %(
    "-" if amount < 0 else "", 
    currency, 
    ('{:%d,.2f}'%(len(str(amount))+3)).format(abs(amount)).lstrip())

lalu,

>>> converter(123132132.13, "$")
'$123,132,132.13'

>>> converter(-123132132.13, "$")
'-$123,132,132.13'
mu 無
sumber
Sebagian besar negara menggunakan simbol mata uang setelah jumlahnya, bukan sebaliknya.
Jonas Byström
@jonas Mungkin itulah yang dilakukan sebagian besar negara, tetapi OP memilikinya sebelum jumlahnya, maka saya sudah mendapatkannya sebelum jumlah dalam jawaban saya juga :)
mu 無
0

Kode python sederhana!

def format_us_currency(value):
    value=str(value)
    if value.count(',')==0:
        b,n,v='',1,value
        value=value[:value.rfind('.')]
        for i in value[::-1]:
            b=','+i+b if n==3 else i+b
            n=1 if n==3 else n+1
        b=b[1:] if b[0]==',' else b
        value=b+v[v.rfind('.'):]
    return '$'+(value.rstrip('0').rstrip('.') if '.' in value else value)
Vanjith
sumber
1
Kode pengembalian Anda string seperti "$2,129.1468284147656", "$10,948.3742933", "$1,0908". Mengacaukan tali.
Eugene Gr. Philippov
Ya saya tidak perhatikan. Anda telah memberikan ans juga.
Vanjith