Formattazione della valuta in Python


156

Sto cercando di formattare un numero come 188518982.18 a £ 188.518.982,18 usando Python.

Come posso fare questo?


Hai fatto un ottimo punto in un commento qui sotto, @RailsSon: vuoi stampare £ s per visualizzare una valuta specifica, ma impiega quella visualizzazione usando un'espressione giapponese per i numeri finanziari. Trovo strano che la tua richiesta non sia stata implementata nella lingua disaccoppiando l' localeuso del valore di valuta del modulo e le proprietà di visualizzazione di quella valuta.
Droogans,

Risposte:


212

Vedi il modulo locale .

Questo fa la formattazione di valuta (e data).

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

15
Come formattare correttamente una valuta non nativa, supponiamo di mostrare un costo in sterline inglesi per un rapporto in lingua giapponese?
SingleNegationElimination

2
@TokenMacGuy: Questa è una domanda trabocchetto. Rapporto giapponese significa virgola giapponese e regole per i decimali ma il simbolo di valuta GB Pound - non banalmente supportato da Locale. Devi creare una definizione locale personalizzata.
S.Lott

se il numero del donatore è negativo restituisce il valore tra "()" perché?
Panchicore,

6
Questo non ha ancora funzionato per me, ma l'ho cambiato locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')e ha funzionato perfettamente!
Furbeenator,

2
@panchicore la notazione per i numeri negativi come indicato dalle parentesi è una pratica comune nel mondo della contabilità. Provalo in oocalc o Excel, e formatta i numeri sul tipo di contabilità.
Droogans,

94

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


6
È pulito ma in realtà non risponde alla domanda, poiché la soluzione richiesta includerebbe un simbolo di valuta e stai anche codificando il numero di cifre dopo il decimale, che è specifico della locale. Esistono molti altri motivi per utilizzare la risposta della locale accettata se non si desidera solo il posizionamento delle virgole.
mrooney,

6
@mrooney Ci sono anche molti motivi per non usare la risposta di locale accettata, come non importare un intero modulo.
Josh,

1
@Josh, "dalla valuta di importazione locale".
Andrew H,

5
@mrooney: puoi semplicemente fare: '$ {: 0, .2f}'. formato (184467616.1), e ora hai il simbolo
triunenature

@triunenature che potrebbe comportare a $ 123,456.78volte però. Modifica: il markdown elimina gli spazi extra, fingendo che ci sia più tra $ e i numeri
CyberJacob

48

Non sono sicuro del perché non sia menzionato più online (o su questa discussione), ma Babel pacchetto (e le utility Django) dei ragazzi di Edgewall è fantastico per la formattazione della valuta (e molte altre attività di i18n). È bello perché non soffre della necessità di fare tutto a livello globale come il modulo locale Python di base.

L'esempio fornito dall'OP sarebbe semplicemente:

>>> import babel.numbers
>>> import decimal
>>> babel.numbers.format_currency( decimal.Decimal( "188518982.18" ), "GBP" )
£188,518,982.18

2
Nota molto tardi: testando questo, non sembra formattare in modo intelligente la valuta, in quanto attacca semplicemente il simbolo appropriato prima dell'importo (formattato in quella che sembra essere la locale che hai impostato, il che è ragionevole), indipendentemente dal fatto che quella valuta effettivamente usa il suo simbolo come prefisso.
Kungphu,

@kungphu Cosa intendi? Vedi babel.pocoo.org/en/latest/api/…
Julian

1
@Julian Sembra che l' localeargomento format_currencypossa essere usato per affrontare questo problema, ma o quello non era nel documento quattro anni fa (quando ho scritto quel commento) o ho appena testato il codice di questa risposta così com'è senza controllare il documento.
Kungphu,

1
@kungphu Gotcha. Ieri non avrei prestato attenzione all'età di questo post. La modifica della documentazione / funzione sembra molto probabile. Saluti!
Julian,

32

Questo è un post antico, ma ho appena implementato la seguente soluzione che:

  • Non richiede moduli esterni
  • Non richiede la creazione di una nuova funzione
  • Può essere fatto in linea
  • Gestisce più variabili
  • Gestisce importi in dollari negativi

Codice:

num1 = 4153.53
num2 = -23159.398598

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

Produzione:

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

E per il poster originale, ovviamente, basta passare $a£


il mio formato aveva bisogno di personalizzazioni, ma va bene perché sono stato in grado di farlo con questa soluzione.
DonkeyKong,

10
Bella idea! Con Python 3.6 e stringhe a F, sembra ancora più bello:print(f'Value is: ${value:,.2f}'.replace('$-', '-$'))
Timo Saloranta,

16

Le mie impostazioni locali sembravano incomplete, quindi ho guardato troppo oltre questa risposta SO e ho trovato:

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

Indipendente dal sistema operativo

Volevo solo condividere qui.


Ma dove chiamiamo il def moneyfmt(value, places=2, curr='', sep=',', dp='.', pos='', neg='-', trailneg='')?
Roel,

9

Se stai usando OSX e non hai ancora impostato le impostazioni del tuo modulo locale questa prima risposta non funzionerà riceverai il seguente errore:

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.

Per porre rimedio a ciò dovrai utilizzare quanto segue:

locale.setlocale(locale.LC_ALL, 'en_US')

2
locale.setlocale (locale.LC_ALL, 'en_US.UTF-8') fa per me
alexblum

9

"{:0,.2f}".format(float(your_numeric_value))in Python 3 fa il lavoro; dà qualcosa come una delle seguenti righe:

10,938.29
10,899.00
10,898.99
2,328.99

6

Se fossi in te, userei BABEL: http://babel.pocoo.org/en/latest/index.html

from babel.numbers import format_decimal


format_decimal(188518982.18, locale='en_US')

1
Il modulo locale di Python non ha funzionato per me (qualunque sia la locale che ho impostato, si è lamentato) ma richiedere babel e usare questa funzione è carino. Vale la pena dare un'occhiata ai documenti API in quanto vi sono più parametri e funzioni più utili (come per le valute:) format_currency.
Daniel W.

3

Oh, è una bestia interessante.

Ho trascorso molto tempo a fare le cose bene, ci sono tre problemi principali che differiscono da locale a locale: - simbolo e direzione della valuta - separatore delle migliaia - punto decimale

Ho scritto la mia implementazione piuttosto estesa di questo che fa parte del framework kiwi python, controlla la fonte LGPL: ed qui:

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

Il codice è leggermente specifico per Linux / Glibc, ma non dovrebbe essere troppo difficile da adottare su Windows o altri unix.

Una volta installato, è possibile effettuare le seguenti operazioni:

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

Che poi ti darà:

'$10.50'

o

'10,50 kr'

A seconda della locale attualmente selezionata.

Il punto principale che questo post ha sull'altro è che funzionerà con le versioni precedenti di Python. locale.currency è stato introdotto in Python 2.5.


Ha dei vantaggi rispetto a locale.currency ()?
Ali Afshar,

@AliAfshar: un vantaggio sarebbe 10,50 krinvece di kr 10,50.
user2394284

2

#printing della variabile "Totale:" in un formato simile a "9.348.237"

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

dove "{: 7, .3f}" è il numero di spazi per la formattazione del numero in questo caso è un milione con 3 punti decimali. Quindi aggiungi '.format (zum1). Lo zum1 è la variabile che ha il grande numero per la somma di tutti i numeri nel mio programma particolare. La variabile può essere qualsiasi cosa tu decida di utilizzare.


1

Ispirato al codice sopra: 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


0

Un lambda per calcolarlo all'interno di una funzione, con l'aiuto della risposta di @ Nate

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

e poi,

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

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

La maggior parte dei paesi utilizza il simbolo della valuta dopo l'importo, non viceversa.
Jonas Byström,

@jonas Forse è quello che fanno la maggior parte dei paesi, ma OP l'aveva prima dell'importo, quindi l'ho anche prima dell'importo nella mia risposta :)
mu 無

0

Semplice codice Python!

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)

1
Il tuo codice restituisce stringhe come "$2,129.1468284147656","$10,948.3742933" , "$1,0908". Colpisce la corda.
Eugene Gr. Filippov

Sì, non me ne sono accorto. Hai dato anche ans.
Vanjith
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.