2013-02-25 2 views
13

Ho passato innumerevoli ore a cercare, leggere, testare e, alla fine, confuso e sgomentato dalla mancanza del concetto più fondamentale dell'oggetto Python's Decimal: Formattare l'output di un decimale in una stringa.Formato oggetto decimale Python con una precisione specificata

Supponiamo abbiamo alcune stringhe o oggetti decimali con i seguenti valori:

0.0008 
    11.1111 
222.2222 
3333.3333 
1234.5678 

L'obiettivo è quello di impostare semplicemente la precisione del decimale alla seconda cifra decimale. Ad esempio, 11.1111 verrà formattato come 11.11 e 1234.5678 come 1234.57.

immagino codice simile al seguente:

import decimal 
decimals = [ 
    decimal.Decimal('0.0008'), 
    decimal.Decimal('11.1111'), 
    decimal.Decimal('222.2222'), 
    decimal.Decimal('3333.3333'), 
    decimal.Decimal('1234.5678'), 
] 
for dec in decimals: 
    print dec.as_string(precision=2, rounding=ROUND_HALF_UP) 

L'uscita risultante sarebbe:

0.00 
11.11 
222.22 
3333.33 
1234.57 

Ovviamente non può fare uso di precisione del contesto del decimale, perché questo tiene conto della TOTAL numero di cifre, non solo precisione decimale.

Non mi interessa anche la conversione del decimale in float per l'output del suo valore. L'INTERO motivo dietro Decimal è di evitare l'archiviazione e l'esecuzione di calcoli sui float.

Quali altre soluzioni ci sono? Capisco che ci sono molte altre domande simili sullo stack overflow, ma nessuna di esse ha trovato la soluzione per risolvere il problema sottostante.

Grazie mille!

risposta

22

Basta usare string formatting o format() function:

>>> for dec in decimals: 
... print format(dec, '7.2f') 
... 
    0.00 
    11.11 
222.22 
3333.33 
1234.57 

decimal.Decimal supporta lo stesso format specifications come carri fanno, in modo da poter utilizzare esponente, punto fisso, in generale, il numero o la formattazione percentuale a seconda delle necessità.

Questo è il metodo ufficiale e pignolo per la formattazione dei decimali; la classe Decimal implementa il metodo .__format__() per gestire tale formattazione in modo efficiente.

+0

Non esiste un'interfaccia decimale incorporata per gestire la formattazione dell'output o la precisione decimale? –

+3

@JoshuaBurns: questa * è * l'interfaccia integrata per la formattazione dell'output. –

+2

che sicuramente risponde alla mia domanda, grazie mille! la mia più grande preoccupazione era che format() stava gettando il valore su un float prima di eseguire il formato attuale. –

2
def d(_in, decimal_places = 3): 
    ''' Convert number to Decimal and do rounding, for doing calculations 
     Examples: 
      46.18271 to 46.183 rounded up 
      46.18749 to 46.187 rounded down 
      117.34999999999999 to 117.350 
     _rescale is a private function, bad practice yet works for now. 
    ''' 
    return Decimal(_in)._rescale(-decimal_places, 'ROUND_HALF_EVEN') 

Edit: Anche in questo caso, _rescale() non è pensato per essere utilizzato da noi bipedi regolari, funziona in Python 2.7, non è disponibile in 3.4.

+0

C'è una ragione per cui non è possibile confrontare direttamente un virgola mobile e un decimale in python? –