- Форматирование поплавков в Python без лишних нулей
- 17 ответов
- Как форматировать числа с плавающей запятой без завершающих нулей?
- Метод 1: Использование функций to_integral() и normalize()
- Способ 2: удаление нулей с помощью функций str() и rstrip()
- Способ 3: использование цикла while
- Способ 4: упрощение с помощью функции float()
- Заключение:
Форматирование поплавков в Python без лишних нулей
Этот пример не имеет никакого смысла вообще. 3.14 == 3.140 — это одно и то же число с плавающей запятой. В этом отношении 3.140000 — это то же самое число с плавающей точкой. Ноль не существует в первую очередь.
@S.LottS.Lott — я думаю, что проблема в ПЕЧАТИ номера с плавающей точкой без конечных нулей, а не в реальной эквивалентности двух чисел.
@pokstad: в этом случае нет «лишнего» нуля. %0.2f и %0.3f — это два формата, необходимые для получения последних чисел слева. Используйте %0.2f чтобы получить последние два числа справа.
3.0 -> «3» по-прежнему допустимый вариант использования. print( ‘<:,g>‘.format( X ) работал для меня, чтобы вывести 3 где X = 6 / 2 а когда X = 5 / 2 я получил выход 2.5 как и ожидалось.
17 ответов
Me, я бы сделал (‘%f’ % x).rstrip(‘0’).rstrip(‘.’) — гарантирует форматирование с фиксированной запятой, а не научную нотацию и т.д. и т.д. Да, не такой гладкий и элегантный, как %g , но он работает (и я не знаю как заставить %g никогда не использовать научную нотацию, -).
Спасибо, это работает именно так, как я хотел! К сожалению, нет такого типа представления для такого рода поведения .
@TarGz, согласился, конечно, было бы более элегантно иметь для этого несколько% -флагов. Подход современного Python см. В docs.python.org/library/… — но, похоже, он ведет себя в отношении вашей конкретной проблемы точно так же, как ‘%g’ % x раньше, у него просто возможно более приятный синтаксис. Кроме того, теперь вы можете string.Formatter подклассы string.Formatter для выполнения собственных настроек.
@alexanderlukanin13 alexanderlukanin13, поскольку точность по умолчанию равна 6, см. docs.python.org/2/library/string.html : ‘f’ Fixed point. Displays the number as a fixed-point number. The default precision is 6. Вы должны использовать «% 0.7f» в приведенном выше решении.
@derenio Хороший вопрос 🙂 Я могу только добавить, что повышение точности выше ‘%0.15f’ — плохая идея, потому что начинают происходить странные вещи .
@alexanderlukanin13 alexanderlukanin13 справа, ~ 15,95 десятичных знаков — это предел для «двойной точности» (64 бита), для «одинарной точности» (32 бита) это ~ 7,22 десятичных знака.
Это не полный ответ на вопрос, например (‘% f’% 15.10) .rstrip (‘0’). Rstrip (‘.’) Return ’15 .100001 ‘, который не тот, о котором он спрашивает, но у меня нет лучшего ответа, как чтобы избежать этой неточности
Если вы находитесь в середине какой-то другой строки: print(‘In the middle <> and something else’.format(‘<:f>‘.format(a).rstrip(‘0’)))
rstrip Мартелли, rstrip от команды double rstrip . Просто используйте это вместо этого, чтобы убрать как точку ( . ), Так и все завершающие нули впоследствии в одной операции: (‘%f’ % x).rstrip(‘.0’)
Вы можете использовать %g для достижения этой цели:
или, для Python 2.6 или выше:
Из docs для format : g вызывает (между прочим)
несущественные конечные нули [будут] удалены из значимости, а десятичная точка также удаляется, если после него не осталось оставшихся цифр.
О, почти! Иногда он форматирует число с плавающей точкой в научной нотации («2.342E + 09») — возможно ли его отключить, то есть всегда показывать все значащие цифры?
Зачем использовать ‘<0. >‘.format(value) если вы можете использовать format(value, ‘. ‘) ? Это исключает необходимость разбора спецификатора формата из строки шаблона, которая в противном случае пуста.0.>
@MartijnPieters: минимальные затраты на разбор спецификатора формата затоплены другими накладными расходами AFAICT; на практике мои локальные тесты для 3.6 (с функцией определения объема микробенчмарка для точного моделирования реального кода) имеют format(v, ‘2.5f’) ~ 10% больше времени, чем ‘<:2.5f>‘.format(v) . Даже если это не так, я склонен использовать форму метода str потому что, когда мне нужно настроить его, добавить к нему дополнительные значения и т. Д., Есть меньше изменений. Конечно, с 3.6 у нас есть f-строки для большинства целей. 🙂
После просмотра ответов на несколько похожих вопросов это кажется лучшим решением для меня:
def floatToString(inputValue): return ('%.15f' % inputValue).rstrip('0').rstrip('.')
%g не избавляется от научной нотации.
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
К сожалению, работает только с числами, которые содержат менее чем примерно пять или более цифр слева от десятичного знака. floatToString(12345.6) возвращает значение ‘12345.600000000000364’ . Уменьшение 15 в %.15f до меньшего числа решает его в этом примере, но это значение нужно уменьшать все больше и больше, когда число увеличивается. Он может быть динамически рассчитан на основе log-base-10 числа, но это быстро становится очень сложным.
Одним из способов решения этой проблемы может быть ограничение длины целого числа (а не только цифр после десятичной дроби): result = (‘%15f’ % val).rstrip(‘0’).rstrip(‘.’).lstrip(‘ ‘)
@JohnSpeeks Я не уверен, что этого можно избежать. Это побочный эффект от того, что плавающие числа не способны отображать точность, если на левой стороне требуется больше цифр. Из того, что я могу сказать, число, которое появляется как строка, является тем же самым числом, которое входит как число с плавающей запятой, или по крайней мере самое близкое его представление. >>>12345.600000000000364 == 12345.6 True
Как пробовать самый простой и, вероятно, самый эффективный подход? Метод 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()
Как форматировать числа с плавающей запятой без завершающих нулей?
Дроби при преобразовании в десятичные часто приводят к строке цифр после запятой. Не является окончательным то, что количество цифр после десятичной точки остается небольшим. Эти цифры становятся неуместными, особенно когда они состоят исключительно из конечных нулей. В этой статье мы углубимся в нюансы удаления конечных нулей из значений с плавающей запятой, используя каждый из приведенных ниже методов.
Python предлагает четыре эффективных метода удаления конечных нулей из значений с плавающей запятой: функции to_integral() и normalize(), функции str() и rstrip(), цикл while и функция float(). Эти методы обеспечивают различные подходы к очистке ваших чисел с плавающей запятой и устранению ненужных конечных нулей.
Метод 1: Использование функций to_integral() и normalize()
Два инструмента лучше, чем один, что удваивает наши возможности в обработке конечных нулей. Это верно в том случае, когда мы пытаемся совместить две функции из десятичная дробь библиотека для удаления конечных нулей в данном вводе.
to_integral() используется для проверки того, благословлено ли данное входное число дробной частью или нет, в то время как нормализовать ( ) Функция используется для удаления конечных нулей без какой-либо дымки.
Нужно начать с импорта десятичная дробь библиотеку, как показано ниже.
from decimal import Decimal
Затем пришло время ввести входные данные, а затем определить пользовательскую функцию, чтобы объединить возможности to_интеграл() и нормализовать ( ) как показано ниже.
ip = Decimal('1.7670000') def remove(n): return n.quantize(Decimal(1)) if n == n.to_integral() else n.normalize()
Наконец, давайте посмотрим на результат.
Способ 2: удаление нулей с помощью функций str() и rstrip()
Это немного необычно, поскольку включает преобразование входного числа в строку, а затем удаление завершающих нулей с помощью оператора рстрип ( ) функция. Это может показаться нетрадиционным, но эффективно справляется со своей задачей!
Начнем с импорта десятичная дробь library с последующим объявлением ввода, как показано ниже.
from decimal import Decimal ip = Decimal('1.48975480000')
Затем ввод преобразуется в строку с помощью ул( ) функция.
Преобразованный вывод передается через рстрип ( ) функция, в которой следует указать, что удаляемый объект равен нулю, поскольку значение по умолчанию — «пустое пространство».
op = string.rstrip('0') print ("Truncated output:", Decimal(op))
Способ 3: использование цикла while
Классический цикл while также может быть очень полезен для удаления конечных нулей, как показано ниже.
ip = "314.509837460000000" print("Input number:", ip) while (ip[-1] == '0'): ip = ip[:-1] print("Truncated number", ip)
Код предназначен для того, чтобы каждый конечный ноль удалялся один за другим в тот момент, когда ввод зацикливался на коде.
Способ 4: упрощение с помощью функции float()
плавать( ) функция преобразует данный вход строго в число с плавающей запятой без пробелов для любых завершающих нулей. Это довольно простой метод удаления конечных нулей, если они есть в данном вводе.
ip = "314.509837460000000" print("Input number:", ip) op = float(ip) print("Truncated number:", op)
Заключение:
Теперь, когда мы подошли к концу этой статьи, мы надеемся, что эта статья предоставила четкое объяснение различных методов, которые можно использовать для удаления конечных нулей из чисел с плавающей запятой в Python. Вот еще одна статья, в которой подробно описано, как использовать форматирование содержимого MS Excel с помощью to_Excel и Стайлер функции в Python. В AskPython есть множество других приятных и не менее информативных статей, которые могут быть очень полезны тем, кто хочет повысить свой уровень в Python. Чтобы еще больше бросить себе вызов, можете ли вы придумать другие способы удаления конечных нулей из чисел с плавающей запятой?