2013-02-25 17 views
13

Spędziłem niezliczoną ilość godzin na badaniu, czytaniu, testowaniu i ostatecznie zdezorientowany i przerażony brakiem najbardziej podstawowej koncepcji Pythona: Formatowanie wyniku dziesiętnego na ciąg.Format Python Obiekt dziesiętny do określonej precyzji

Załóżmy mamy pewne ciągi lub dziesiętne obiekty z następujących wartości:

0.0008 
    11.1111 
222.2222 
3333.3333 
1234.5678 

Celem jest po prostu ustawić dokładność po przecinku do drugiego miejsca po przecinku. Np. 11.1111 zostałby sformatowany jako 11.11 i 1234.5678 jako 1234.57.

wyobrażam sobie kod podobny do poniższego:

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) 

Wynikiem będzie:

0.00 
11.11 
222.22 
3333.33 
1234.57 

Oczywiście nie możemy skorzystać z dokładnością po przecinku za kontekstu, bo ten uwzględnia całkowitej liczba cyfr, a nie tylko dokładność dziesiętna.

Nie jestem również zainteresowany konwersją wartości dziesiętnej na wartość zmiennoprzecinkową, aby uzyskać wartość. CAŁKOWITĄ przyczyną dziesiętnej jest unikanie przechowywania i wykonywania obliczeń na pływach.

Jakie są inne rozwiązania? Rozumiem, że istnieje wiele innych podobnych pytań dotyczących przepełnienia stosu, ale żaden z nich nie rozwiązał problemu, o który pytam.

Wielkie dzięki!

Odpowiedz

22

Wystarczy użyć string formatting lub format() function:

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

decimal.Decimal obsługuje ten sam format specifications jako pływaki roboty, dzięki czemu można używać wykładnik, stały punkt, ogólne, numer lub formatowania procentowego w miarę potrzeb.

To jest oficjalna i pythonic metoda formatowania miejsc dziesiętnych; Klasa Decimal implementuje metodę .__format__(), aby efektywnie obsługiwać takie formatowanie.

+0

czy nie ma wbudowanego interfejsu dziesiętnego do obsługi formatowania wyjściowego lub dokładności dziesiętnej? –

+3

@JoshuaBurns: To * jest * wbudowanym interfejsem do formatowania wyjściowego. –

+2

, który zdecydowanie odpowiada na moje pytanie, dziękuję bardzo! Moim największym zmartwieniem było to, że format() wyrzucił wartość do wartości zmiennoprzecinkowej przed wykonaniem właściwego formatu. –

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: Znowu _rescale() nie jest przeznaczona do wykorzystania przez nas regularne dwunogi, to działa w Pythonie 2.7, nie jest dostępna w 3.4.

+0

Czy istnieje powód, dla którego nie można bezpośrednio porównać Float i Decimal w python? –