Самый питонический способ печати * не более * некоторого количества десятичных знаков

Я хочу отформатировать список чисел с плавающей запятой максимум, скажем, с двумя десятичными знаками. Но мне не нужны конечные нули и конечные десятичные точки.

Так, например, 4.001 => 4, 4.797 => 4.8, 8.992 => 8.99, 13.577 => 13.58.

Простое решение - ('%.2f' % f).rstrip('.0') ('%.2f' % f).rstrip('0').rstrip('.'). Но это выглядит довольно некрасиво и кажется хрупким. Какие-нибудь более приятные решения, может быть, с некоторыми волшебными флагами формата?


person nneonneo    schedule 21.02.2013    source источник
comment
Я упустил здесь суть или как насчет функции round(): docs.python. org / 2 / library / functions.html # round   -  person TerryA    schedule 21.02.2013
comment
Хотя, я должен сказать, я не большой поклонник решений, которые включают round просто потому, что я нервничаю, я когда-нибудь получу 1.1000000000009962 в качестве результата.   -  person nneonneo    schedule 21.02.2013
comment
Аарр, это не дубликат! Я не хочу отставать .0. Другой вопрос позволяет это.   -  person nneonneo    schedule 21.02.2013
comment
@nneonneo Я считаю, что int() избавится от .0, но используйте его с осторожностью, так как он избавится от любых других десятичных знаков (так что, возможно, оператор if / else?)   -  person TerryA    schedule 21.02.2013
comment
@Haidro: ... теперь это становится неприятно. Я надеялся, что мне не нужен if/else, или я просто поставлю условие на '.%2f' % f или что-то в этом роде. (Все еще странно сложно иметь хорошее решение ... Я действительно привык к тому, что в Python все очень просто)   -  person nneonneo    schedule 21.02.2013
comment
Ох, кто-то заметил, что ('%.2f' % f).rstrip('.0') искажает 1000.0 на 1. Итак, теперь нам нужно _4 _...   -  person nneonneo    schedule 21.02.2013


Ответы (3)


Вам нужно разделить 0 и . зачистку; таким образом вы никогда не избавитесь от естественного 0.

В качестве альтернативы используйте функцию format(), но на самом деле это сводится к одному и тому же:

format(f, '.2f').rstrip('0').rstrip('.')

Некоторые тесты:

>>> def formatted(f): return format(f, '.2f').rstrip('0').rstrip('.')
... 
>>> formatted(0.0)
'0'
>>> formatted(4.797)
'4.8'
>>> formatted(4.001)
'4'
>>> formatted(13.577)
'13.58'
>>> formatted(0.000000000000000000001)
'0'
>>> formatted(10000000000)
'10000000000'
person Martijn Pieters    schedule 21.02.2013
comment
+1: Думаю, к такому выводу я пришел независимо. Я надеялся, что есть решение получше, но его просто не могло быть. Спасибо! - person nneonneo; 21.02.2013

Модуль форматирования g ограничивает вывод до n значащих цифр, отбрасывая конечные нули:

>>> "{:.3g}".format(1.234)
'1.23'
>>> "{:.3g}".format(1.2)
'1.2'
>>> "{:.3g}".format(1)
'1'
person Tim Pietzcker    schedule 21.02.2013
comment
Вы можете использовать format() функцию, если у вас есть только один {} шаблон . например format(f, '.3g'). Это правильно работает даже для 0. - person Martijn Pieters; 21.02.2013
comment
Почти ... за исключением того, что он печатает максимум три цифры, а не максимум два десятичных знака. (Пример: '{:.3g}'.format(13.468) печатает 13.5, а не 13.47) - person nneonneo; 21.02.2013
comment
Ах, и это тоже неправильно, когда задействованы экспоненты. - person Martijn Pieters; 21.02.2013
comment
Хорошо, я думаю, вы могли бы сделать "{0:.{1}g}".format(13.468, 2+len(str(int(13.468)))), но это не совсем Pythonic, я думаю :) - person Tim Pietzcker; 21.02.2013

В общем, работа со String [s] может быть медленной. Однако это другое решение:

>>> from decimal import Decimal
>>> precision = Decimal('.00')
>>> Decimal('4.001').quantize(precision).normalize()
Decimal('4')
>>> Decimal('4.797').quantize(precision).normalize()
Decimal('4.8')
>>> Decimal('8.992').quantize(precision).normalize()
Decimal('8.99')
>>> Decimal('13.577').quantize(precision).normalize()
Decimal('13.58')

Дополнительную информацию можно найти здесь: http://docs.python.org/2/library/decimal.html

person Markon    schedule 21.02.2013