web-dev-qa-db-ja.com

Python string.format()パーセンテージを小数点第1位まで

以下の例では、小数点以下1桁にフォーマットしたいのですが、pythonは数値を切り上げるのが好きなようですが、数値を切り上げないようにする方法はありますか?

>>> '{:.1%}'.format(0.9995)
'100.0%'
>>> '{:.2%}'.format(0.9995)
'99.95%'

ありがとう! :)

24
Ashy

alwaysを(最も近い精度に丸める代わりに)切り捨てる場合は、 math.floor()関数

from math import floor

def floored_percentage(val, digits):
    val *= 10 ** (digits + 2)
    return '{1:.{0}f}%'.format(digits, floor(val) / 10 ** digits)

print floored_percentage(0.995, 1)

デモ:

>>> from math import floor
>>> def floored_percentage(val, digits):
...     val *= 10 ** (digits + 2)
...     return '{1:.{0}f}%'.format(digits, floor(val) / 10 ** digits)
... 
>>> floored_percentage(0.995, 1)
'99.5%'
>>> floored_percentage(0.995, 2)
'99.50%'
>>> floored_percentage(0.99987, 2)
'99.98%'
14
Martijn Pieters

このようなもの:

def my_format(num, x):
     return str(num*100)[:4 + (x-1)] + '%'

>>> my_format(.9995, 1)
'99.9%'
>>> my_format(.9995, 2)
'99.95%'
>>> my_format(.9999, 1)
'99.9%'
>>> my_format(0.99987, 2)
'99.98%'
1

いくつかの方法がありますが、おそらく最も簡単な方法は

x = str(10. * 0.9995).split('.')
my_string = '%s.%s%%' % (x[0], x[1][:2])

これにより、小数点が常に正しい場所にあることが保証されます(1.0000または0.001などのEdgeの場合)。

0
danodonovan

Python 3.6+を使用すると、f-stringsとも呼ばれるフォーマット済み文字列リテラルを使用できます。これらはstr.formatよりも効率的です。さらに、代わりにより効率的なフロア除算を使用できますof math.floor。私の意見では、構文も読みやすくなっています。

両方の方法を比較のために以下に示します。

from math import floor
from random import random

def floored_percentage(val, digits):
    val *= 10 ** (digits + 2)
    return '{1:.{0}f}%'.format(digits, floor(val) / 10 ** digits)

def floored_percentage_jpp(val, digits):
    val *= 10 ** (digits + 2)
    return f'{val // digits / 10 ** digits:.{digits}f}%'

values = [random() for _ in range(10000)]

%timeit [floored_percentage(x, 1) for x in values]      # 35.7 ms per loop
%timeit [floored_percentage_jpp(x, 1) for x in values]  # 28.1 ms per loop
0
jpp