Форматирование поплавков в Python без конечных нулей - программирование
Подтвердить что ты не робот

Форматирование поплавков в Python без конечных нулей

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

Например:

3 -> "3"
3. -> "3"
3.0 -> "3"
3.1 -> "3.1"
3.14 -> "3.14"
3.140 -> "3.14"
4b9b3361

Ответ 1

Me, я бы сделал ('%f' % x).rstrip('0').rstrip('.') - гарантирует форматирование с фиксированной запятой, а не научную нотацию и т.д. и т.д. Да, не такой гладкий и элегантный, как %g, но он работает (и я не знаю как заставить %g никогда не использовать научную нотацию, -).

Ответ 2

Вы можете использовать %g для достижения этой цели:

'%g'%(3.140)

или, для Python 2.6 или выше:

'{0:g}'.format(3.140)

Из docs для format: g вызывает (между прочим)

несущественные конечные нули [будут] удалены из значимости, а десятичная точка также удаляется, если после него не осталось оставшихся цифр.

Ответ 3

Как пробовать самый простой и, вероятно, самый эффективный подход? Метод normalize() удаляет все самые правые конечные нули.

from decimal import Decimal

print (Decimal('0.001000').normalize())
# Result: 0.001

Работает в Python 2 и Python 3.

- Обновлено -

Единственная проблема, о которой говорил @BobStein-VisiBone, заключается в том, что цифры, такие как 10, 100, 1000... будут отображаться в экспоненциальном представлении. Это можно легко исправить, используя следующую функцию:

from decimal import Decimal


def format_float(f):
    d = Decimal(str(f));
    return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()

Ответ 4

После просмотра ответов на несколько похожих вопросов это кажется лучшим решением для меня:

def floatToString(inputValue):
    return ('%.15f' % inputValue).rstrip('0').rstrip('.')

Мое рассуждение:

%g не избавляется от научной нотации.

>>> '%g' % 0.000035
'3.5e-05'

15 десятичных знаков, похоже, избегают странного поведения и имеют большую точность для моих потребностей.

>>> ('%.15f' % 1.35).rstrip('0').rstrip('.')
'1.35'
>>> ('%.16f' % 1.35).rstrip('0').rstrip('.')
'1.3500000000000001'

Я мог бы использовать format(inputValue, '.15f'). вместо '%.15f' % inputValue, но это немного медленнее (~ 30%).

Я мог бы использовать Decimal(inputValue).normalize(), но в этом есть несколько проблем. Во-первых, он медленнее (~ 11x). Я также обнаружил, что, хотя он имеет довольно высокую точность, он по-прежнему страдает от потери точности при использовании normalize().

>>> Decimal('0.21000000000000000000000000006').normalize()
Decimal('0.2100000000000000000000000001')
>>> Decimal('0.21000000000000000000000000006')
Decimal('0.21000000000000000000000000006')

Самое главное, что я все равно буду преобразовываться в Decimal из float, который может заставить вас получить что-то другое, кроме числа, которое вы там вложили. Я думаю, что Decimal работает лучше всего, когда арифметика остается в Decimal, а Decimal инициализируется строкой.

>>> Decimal(1.35)
Decimal('1.350000000000000088817841970012523233890533447265625')
>>> Decimal('1.35')
Decimal('1.35')

Я уверен, что проблема с точностью Decimal.normalize() может быть скорректирована с учетом настроек контекста, но, учитывая уже медленную скорость и не требующую смешной точности, и тот факт, что я все еще буду преобразовывать из float и во всяком случае, потеря точности, я не думал, что это стоит того, чтобы преследовать.

Меня не интересует возможный результат "-0", поскольку -0.0 является допустимым числом с плавающей запятой, и, вероятно, это будет редкое событие, но, поскольку вы упоминали, что хотите сохранить строковый результат короче возможно, вы всегда можете использовать дополнительные условные условия при очень низкой стоимости дополнительной скорости.

def floatToString(inputValue):
    result = ('%.15f' % inputValue).rstrip('0').rstrip('.')
    return '0' if result == '-0' else result

Ответ 5

Вот решение, которое сработало для меня. Это смесь решения PolyMesh и нового синтаксиса .format().

for num in 3, 3., 3.0, 3.1, 3.14, 3.140:
    print('{0:.2f}'.format(num).rstrip('0').rstrip('.'))

Выход:

3
3
3
3.1
3.14
3.14

Ответ 6

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

format(3.140, '.10g') где 10 - это точная точность.

Ответ 7

Хотя форматирование, вероятно, является наиболее more_itertools.rstrip для more_itertools.rstrip, здесь есть альтернативное решение с использованием инструмента more_itertools.rstrip.

import more_itertools as mit


def fmt(num, pred=None):
    iterable = str(num)
    predicate = pred if pred is not None else lambda x: x in {".", "0"}
    return "".join(mit.rstrip(iterable, predicate))

assert fmt(3) == "3"
assert fmt(3.) == "3"
assert fmt(3.0) == "3"
assert fmt(3.1) == "3.1"
assert fmt(3.14) == "3.14"
assert fmt(3.140) == "3.14"
assert fmt(3.14000) == "3.14"
assert fmt("3,0", pred=lambda x: x in set(",0")) == "3"

Число преобразуется в строку, в которой отсутствуют завершающие символы, удовлетворяющие предикату. Определение функции fmt не является обязательным, но здесь оно используется для проверки утверждений, которые все проходят. Примечание: он работает со строковыми входами и принимает необязательные предикаты.

Смотрите также подробности об этой сторонней библиотеке, more_itertools.

Ответ 8

>>> str(a if a % 1 else int(a))

Ответ 9

Если вы можете жить с 3. и 3.0, выглядящими как "3.0", очень простой подход, который удаляет нули прямо из представлений с плавающей точкой:

print("%s"%3.140)

(спасибо @ellimilial за указание на исключения)

Ответ 10

Возможно использование функции format:

{}.format(float)

Ответ 11

Я думаю, что есть более простой способ сделать это с помощью новой функциональности str.format. Если вы просто преобразуете его с помощью str (например, str(.0300)0.3), он делает то, что желательно, в основном. Если число мало или достаточно велико, оно будет прибегать к экспоненциальной нотации, но в основном оно будет просто печатать число с плавающей запятой без конечных (или ведущих) нулей. Если строка формата пуста, то она в основном использует вывод str(), поэтому это должно работать, если желаемая функциональность:

'{0}'.format(fp_num)

Даже это должно работать, если это единственное, что формируется:

'{}'.format(fp_num)

Ответ 12

OP хотел бы удалить сверкающие нули и сделать результирующую строку как можно короче.

Я нахожу, что экспоненциальное форматирование% g сокращает результирующую строку для очень больших и очень малых значений. Проблема возникает для значений, которые не нуждаются в экспоненциальной нотации, например, 128.0, которая не очень большая или очень маленькая.

Вот один из способов форматирования чисел как коротких строк, который использует экспоненциальную нотацию% g только тогда, когда Decimal.normalize создает слишком длинные строки. Это может быть не самое быстрое решение (поскольку оно использует Decimal.normalize)

def floatToString (inputValue, precision = 3):
    rc = str(Decimal(inputValue).normalize())
    if 'E' in rc or len(rc) > 5:
        rc = '{0:.{1}g}'.format(inputValue, precision)        
    return rc

inputs = [128.0, 32768.0, 65536, 65536 * 2, 31.5, 1.000, 10.0]

outputs = [floatToString(i) for i in inputs]

print(outputs)

# ['128', '32768', '65536', '1.31e+05', '31.5', '1', '10']

Ответ 13

Для float вы можете использовать это:

def format_float(num):
    return ('%i' if num == int(num) else '%s') % num

Проверьте это:

>>> format_float(1.00000)
'1'
>>> format_float(1.1234567890000000000)
'1.123456789'

Для десятичного числа см. решение здесь: fooobar.com/questions/60707/...

Ответ 14

Обработка% f, и вы должны положить

%.2f

где:.2f ==.00 плавает.

Пример:

печать "Цена:%.2f"% цены [товар]

выход:

Цена: 1.50

Ответ 15

Используйте% g с большой шириной, например '%.99g'. Он будет печатать в нотации с фиксированной точкой для любого достаточно большого числа.

EDIT: он не работает

>>> '%.99g' % 0.0000001
'9.99999999999999954748111825886258685613938723690807819366455078125e-08'

Ответ 16

Вы можете использовать max() следующим образом:

print(max(int(x), x))

Ответ 17

Вы можете достичь этого в большинстве способов pythonic:

python3:

"{:0.0f}".format(num)