Як я можу відформатувати десятковий знак, щоб завжди відображалися два знаки після коми?


237

Я хочу показати:

49 як 49.00

і:

54.9 як 54.90

Незалежно від довжини десяткової чи чи є десяткові знаки, я хотів би відобразити a Decimalз двома знаками після коми, і я хотів би зробити це ефективно. Мета - відображення значень грошей.

наприклад, 4898489.00


4
Вам це потрібно, щоб це було якомога довше? Що це означає? Ви можете додати провідні нулі, поки не закінчиться пам'ять, але я підозрюю, що це не те, що ви хочете ...
Марк Байєрс

Я думаю, це може означати, що ОП використовує decimal.Decimal і не задоволений точністю десяткового контексту, яка обмежує точність до n цифр, як у "n цифрах точності в строгому сенсі" (наприклад, "123.456" стає десятковою ('1.2E + 2 ')), а не "n цифр у дробовій частині" (для десяткової (' 123,45 ')) ... Дивіться мою відповідь на спробу бути корисною у цьому. ;-)
Michał Marczyk

1
Так, вони для грошових цінностей.
orokusaki

Відповіді:


105

Я припускаю, що ви, ймовірно, використовуєте Decimal()об'єкти з decimalмодуля? (Якщо вам знадобиться рівно дві цифри точності за межами десяткових знаків із довільно великими цифрами, ви, безумовно, повинні бути, і ось що підказує назва вашого запитання ...)

Якщо так, то в розділі « Десятковий FAQ» у документах є пара питань / відповідей, яка може бути корисною для вас:

З. У додатку з фіксованою точкою з двома десятковими знаками деякі входи мають багато місць і їх потрібно округлити. В інших не повинно бути зайвих цифр і їх потрібно перевірити. Які методи слід використовувати?

A. Метод квантування () округляє до фіксованої кількості десяткових знаків. Якщо встановлена ​​пастка Inexact, вона також корисна для перевірки:

>>> TWOPLACES = Decimal(10) ** -2       # same as Decimal('0.01')
>>> # Round to two places
>>> Decimal('3.214').quantize(TWOPLACES)
Decimal('3.21')
>>> # Validate that a number does not exceed two places
>>> Decimal('3.21').quantize(TWOPLACES, context=Context(traps=[Inexact]))
Decimal('3.21')
>>> Decimal('3.214').quantize(TWOPLACES, context=Context(traps=[Inexact]))
Traceback (most recent call last):
   ...
Inexact: None

Наступне запитання читається

Q. Як я маю дійсні два місця, як я можу підтримувати цей інваріант протягом програми?

Якщо вам потрібна відповідь на це (поряд з великою кількістю іншої корисної інформації), див . Вищезгаданий розділ Документів . Крім того, якщо ви тримаєте свій Decimals з двома цифрами точності поза десятковою точкою (маючи на увазі стільки точності, скільки потрібно для збереження всіх цифр ліворуч від десяткової крапки і двох праворуч від нього і не більше ...), тоді перетворення їх у рядки з strбуде добре працювати:

str(Decimal('10'))
# -> '10'
str(Decimal('10.00'))
# -> '10.00'
str(Decimal('10.000'))
# -> '10.000'

2
О, забув згадати про ефективність у відповіді ... але я думаю, я все одно не експерт. Я не бачу причин, чому було б особливо неефективно тримати фіксовану кількість "дробових цифр" навколо, хоча будь-які операції, проведені над номерами, можуть потребувати операції округлення результату, щоб привести його у відповідність до вимог ... Для заради ефективності, це, мабуть, слід робити якомога рідше - як безпосередньо перед серіалізацією / роздруком для користувача.
Michał Marczyk

517

Ви повинні використовувати нові специфікації формату, щоб визначити, як ваше значення має бути представлене:

>>> from math import pi  # pi ~ 3.141592653589793
>>> '{0:.2f}'.format(pi)
'3.14'

Документація часом може бути трохи тупою, тому я рекомендую такі, легші для читання посилання:

Python 3.6 представив буквальну інтерполяцію рядкових рядків (також відомий як f-рядки), тому тепер ви можете записати вищезазначене ще більш лаконічно як:

>>> f'{pi:.2f}'
'3.14'

4
@Droogans: Euh ... formatповертає a str, а не a float: print type({0:.2f}".format(pi))повертає <type 'str'>.
BioGeek

На жаль Перевантаження дієслова на слові return. Будь ласка, подумки змініть це на prints.
Droogans

20
Якщо ви не хочете використовувати числовий заповнювач:"{:.2f}".format(pi)
Користувач

Що робить 0:? Я припускаю, що .це частина рядка python
information_interchange

135

Розділ " Операції з форматування рядків " документації на Python містить відповідь, яку ви шукаєте. Коротко:

"%0.2f" % (num,)

Деякі приклади:

>>> "%0.2f" % 10
'10.00'
>>> "%0.2f" % 1000
'1000.00'
>>> "%0.2f" % 10.1
'10.10'
>>> "%0.2f" % 10.120
'10.12'
>>> "%0.2f" % 10.126
'10.13'

Там немає необхідності для 0після того , як %, і не потрібно обернути numв tuple.
user238424

17
Власне, загортання числа в кортеж є умовою кодування для запобігання помилки введення качки на аргументах під час форматування рядків. У цьому випадку це не робить ефекту з плаваючою конверсією, але це запобігає несподіваній помилці типу при перетворенні на рядки. Розглянемо r = 1; "%s" % r; r = (1, 2); "%s" % rпроти r = 1; "%s" % (r,); r = (1,2 ); "%s" % (r,). Таким чином, більшість складних стилів кодування в python зараз використовують безумовний кортеж (і Python 3 знецінив увесь метод форматування рядків як схильний до помилок).
Тревіс Бредшо

Крім того, як хлопець з математичним фоном, "голі" десяткові позначення некрасиві. Ведучий 0 нічого не шкодить і виглядає краще. :)
Тревіс Бредшоу

3
Естетично нічим не відрізняється. Найголовніше, що 0 - це значення за замовчуванням, у будь-якому випадку. Немає абсолютно ніякої шкоди в наданні за замовчуванням, якщо це робить естетично приємний код. Цікаво, скільки розробників вирішили не (не вмієте?) Розмежовувати правильність та стиль. : /
Тревіс Бредшоу

32

Ви можете використовувати оператор форматування рядків так:

num = 49
x = "%.2f" % num  # x is now the string "49.00"

Я не впевнений, що ви маєте на увазі під "ефективним" - це майже точно не вузьке місце вашої заявки. Якщо ваша програма працює повільно, профіліруйте її спочатку, щоб знайти гарячі точки, а потім оптимізуйте їх.


1
Я думаю, що змінна, названа 'f', може бентежити деяких людей. Краще назвати це чимось іншим для прикладу, як Тревіс нижче.
Алек Ландграф

28
>>> print "{:.2f}".format(1.123456)
1.12

Ви можете змінити 2в 2fбудь-яку кількість знаків після коми , які ви хочете показати.

Редагувати:

Від Python3.6цього, це означає:

>>> print(f"{1.1234:.2f}")
1.12

19

.format - це більш зрозумілий спосіб обробки змінного форматування:

'{:.{prec}f}'.format(26.034, prec=2)


6

якщо у вас є кілька параметрів, ви можете використовувати

 print('some string {0:.2f} & {1:.2f}'.format(1.1234,2.345))
 >>> some string 1.12 & 2.35

3

Якщо ви використовуєте це для валюти, а також хочете, щоб значення було відокремлене від ,s, яке ви можете використовувати

$ {:,.f2}.format(currency_value).

наприклад:

currency_value = 1234.50

$ {:,.f2}.format(currency_value) --> $ 1,234.50

Ось трохи коду, який я написав деякий час тому:

print("> At the end of year " + year_string + " total paid is \t$ {:,.2f}".format(total_paid))

> At the end of year   1  total paid is         $ 43,806.36
> At the end of year   2  total paid is         $ 87,612.72
> At the end of year   3  total paid is         $ 131,419.08
> At the end of year   4  total paid is         $ 175,225.44
> At the end of year   5  total paid is         $ 219,031.80   <-- Note .80 and not .8
> At the end of year   6  total paid is         $ 262,838.16
> At the end of year   7  total paid is         $ 306,644.52
> At the end of year   8  total paid is         $ 350,450.88
> At the end of year   9  total paid is         $ 394,257.24
> At the end of year  10  total paid is         $ 438,063.60   <-- Note .60 and not .6
> At the end of year  11  total paid is         $ 481,869.96
> At the end of year  12  total paid is         $ 525,676.32
> At the end of year  13  total paid is         $ 569,482.68
> At the end of year  14  total paid is         $ 613,289.04
> At the end of year  15  total paid is         $ 657,095.40   <-- Note .40 and not .4  
> At the end of year  16  total paid is         $ 700,901.76
> At the end of year  17  total paid is         $ 744,708.12
> At the end of year  18  total paid is         $ 788,514.48
> At the end of year  19  total paid is         $ 832,320.84
> At the end of year  20  total paid is         $ 876,127.20   <-- Note .20 and not .2

0

Найпростіший приклад показати вам, як це зробити:

Код:

>>> points = 19.5 >>> total = 22 >>>'Correct answers: {:.2%}'.format(points/total) `

Вихід: Правильні відповіді: 88,64%


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.