Come posso formattare un decimale per mostrare sempre 2 decimali?


237

Voglio visualizzare:

49 come 49.00

e:

54.9 come 54.90

Indipendentemente dalla lunghezza del decimale o dalla presenza di decimali, vorrei visualizzare un Decimalcon 2 decimali e mi piacerebbe farlo in modo efficiente. Lo scopo è mostrare i valori del denaro.

per esempio, 4898489.00


4
Hai bisogno che sia il più lungo possibile? Cosa significa? Potresti aggiungere zeri iniziali fino a quando non esaurisci la memoria, ma sospetto che non sia quello che vuoi ...
Mark Byers,

Suppongo che potrebbe significare che l'OP utilizza decimale. Decimale ed è insoddisfatto della precisione del contesto decimale che limita la precisione a n cifre come in "n cifre di precisione in senso stretto" (ad esempio "123.456" diventa Decimale ("1.2E + 2 ')) e non "n cifre nella parte frazionaria" (per Decimale (' 123,45 ')) ... Vedi la mia risposta per un tentativo di essere d'aiuto in questo. ;-)
Michał Marczyk,

1
Sì, sono per valori monetari.
Orokusaki,

Risposte:


105

Suppongo che probabilmente stai usando gli Decimal()oggetti dal decimalmodulo? (Se hai bisogno esattamente di due cifre di precisione oltre il punto decimale con numeri arbitrariamente grandi, dovresti assolutamente esserlo, ed è quello che suggerisce il titolo della tua domanda ...)

In tal caso, la sezione FAQ decimali dei documenti ha una coppia di domande / risposte che può essere utile per te:

D. In un'applicazione a virgola fissa con due cifre decimali, alcuni input hanno molte posizioni e devono essere arrotondati. Altri non dovrebbero avere cifre in eccesso e devono essere convalidati. Quali metodi dovrebbero essere usati?

A. Il metodo quantize () arrotonda a un numero fisso di posizioni decimali. Se è impostata la trap Inexact, è anche utile per la convalida:

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

Si legge la domanda successiva

D. Una volta che ho input di due posti validi, come posso mantenere quell'invariante in un'applicazione?

Se hai bisogno di una risposta a questo (insieme a molte altre informazioni utili), consulta la sezione dei documenti di cui sopra . Inoltre, se mantieni le tue Decimals con due cifre di precisione oltre il punto decimale (che significa tutta la precisione necessaria per mantenere tutte le cifre a sinistra del punto decimale e due a destra di esso e non più ...), quindi convertirli in stringhe strfunzionerà bene:

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

2
Oh, ho dimenticato di menzionare l'efficienza nella risposta ... ma credo di non essere comunque un esperto. Non vedo alcun motivo per cui sarebbe particolarmente inefficiente mantenere un numero fisso di "cifre frazionarie", anche se qualsiasi operazione eseguita sui numeri potrebbe richiedere un'operazione di arrotondamento sul risultato per renderlo in linea con i requisiti ... per ragioni di efficienza, questo dovrebbe probabilmente essere fatto il più raramente possibile, proprio come prima della serializzazione / stampa per l'utente.
Michał Marczyk,

517

È necessario utilizzare le nuove specifiche del formato per definire come deve essere rappresentato il valore:

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

La documentazione può essere un po 'ottusa a volte, quindi raccomando i seguenti riferimenti più facili da leggere:

Python 3.6 ha introdotto l'interpolazione letterale di stringhe (nota anche come f-string) in modo da poter scrivere quanto sopra ancora più succinto come:

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

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

Ops. Verbo sovraccarico sulla parola return. Per favore, cambialo mentalmente in prints.
Droogans,

20
Se non si desidera utilizzare il segnaposto numerico:"{:.2f}".format(pi)
Utente

Che cosa 0:fa? Suppongo che .sia parte della stringa Python
information_interchange il

135

La sezione Operazioni di formattazione delle stringhe della documentazione di Python contiene la risposta che stai cercando. In breve:

"%0.2f" % (num,)

Qualche esempio:

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

Non è necessario per il 0dopo %e non è necessario avvolgere numin a tuple.
user238424,

17
In realtà, il wrapping di num in una tupla è una convenzione di codifica per prevenire un errore di battitura di anatra su argomenti durante la formattazione di stringhe. In questo caso non ha alcun effetto con una conversione float, ma impedisce un errore di tipo imprevisto durante la conversione in stringhe. Considerare r = 1; "%s" % r; r = (1, 2); "%s" % rcontro r = 1; "%s" % (r,); r = (1,2 ); "%s" % (r,). Pertanto, gli stili di codifica più sofisticati in Python ora utilizzano la tupla incondizionata (e Python 3 ha deprecato l'intero metodo di formattazione delle stringhe come soggetto a errori).
Travis Bradshaw,

Inoltre, come un ragazzo con un background matematico, la notazione decimale "nuda" è brutta. Lo 0 iniziale non fa male a nulla e sembra migliore. :)
Travis Bradshaw il

3
Esteticamente non è diverso. Ancora più importante, lo 0 è il valore predefinito, comunque. Non c'è assolutamente nulla di male nel fornire il valore predefinito se rende il codice esteticamente piacevole. È interessante il numero di sviluppatori che scelgono di non (non è possibile?) Distinguere tra correttezza e stile. : /
Travis Bradshaw

32

È possibile utilizzare l' operatore di formattazione della stringa in questo modo:

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

Non sono sicuro di cosa intendi per "efficiente", quasi sicuramente non è il collo di bottiglia della tua applicazione. Se il tuo programma funziona lentamente, crea prima un profilo per individuare gli hot spot, quindi ottimizzali.


1
Penso che la variabile chiamata 'f' possa confondere alcune persone. Meglio chiamarlo qualcos'altro per un esempio come Travis di seguito.
Aleck Landgraf,

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

È possibile modificare 2in 2fqualsiasi numero di punti decimali che si desidera mostrare.

MODIFICARE:

Da Python3.6, questo si traduce in:

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

19

.format è un modo più leggibile per gestire la formattazione variabile:

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


6

se hai più parametri puoi usare

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

3

Se lo stai usando per la valuta e vuoi che il valore sia separato da quello ,che puoi usare

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

per esempio:

currency_value = 1234.50

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

Ecco un po 'di codice che ho scritto qualche tempo fa:

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

L'esempio di modo più semplice per mostrarti come farlo è:

Codice :

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

Risultato: risposte corrette: 88,64%


-6

che dire

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


print round(20.2564567 , 4)    >>>>>>>        20.2564
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.