Подтвердить что ты не робот

Форматировать десятичный объект Python с заданной точностью

Я потратил бесчисленное количество часов на исследования, чтение, тестирование и, в конечном счете, запутался и разочаровался в недостатке Python Decimal в самой фундаментальной концепции: Форматирование вывода Decimal в строку.

Предположим, что у нас есть несколько строк или десятичные объекты со следующими значениями:

   0.0008
  11.1111
 222.2222
3333.3333
1234.5678

Цель состоит в том, чтобы просто установить десятичную точность во вторую десятичную точку. Например, 11.1111 будет отформатирован как 11.11 и 1234.5678 как 1234.57.

Я представляю код, похожий на следующий:

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)

Результирующий результат:

0.00
11.11
222.22
3333.33
1234.57

Очевидно, что мы не можем использовать точность контекста Decimal, потому что это учитывает TOTAL количество цифр, а не только десятичную точность.

Я также не заинтересован в преобразовании Decimal в float для вывода его значения. Полная причина Decimal заключается в том, чтобы избежать хранения и выполнения вычислений при поплавках.

Какие еще существуют решения? Я понимаю, что существует много других подобных вопросов при переполнении стека, но ни один из них не нашел для решения основной проблемы, которую я задаю.

Спасибо большое!

4b9b3361

Ответ 1

Просто используйте форматирование строки или format() function:

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

decimal.Decimal поддерживает те же спецификации формата, что и float, поэтому вы можете использовать форматирование, фиксированную точку, общее, числовое или процентное форматирование как необходимо.

Это официальный и питонический метод форматирования десятичных знаков; класс Decimal реализует метод .__format__() для эффективного обработки такого форматирования.

Ответ 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: Опять же, _rescale() не предназначен для использования обычными двунаправленными программами, он работает в Python 2.7, не доступен в версии 3.4.