webentwicklung-frage-antwort-db.com.de

Python string.format () Prozentsatz auf eine Dezimalstelle

Im folgenden Beispiel würde ich gerne auf 1 Dezimalstelle formatieren, aber es scheint, als würde Python die Zahl aufrunden. Gibt es eine Möglichkeit, die Zahl nicht aufrunden zu lassen?

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

Vielen Dank! :)

22
Ashy

Wenn Sie always abrunden möchten (anstatt auf die nächste Genauigkeit zu runden), dann tun Sie dies explizit mit der Funktion 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)

Demo:

>>> 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

Etwas wie das:

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

Es gibt mehrere Möglichkeiten, die vielleicht einfachste ist

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

dadurch wird sichergestellt, dass Sie immer den Dezimalpunkt an der richtigen Stelle haben (für Edge-Fälle wie 1.0000 oder 0.001).

0
danodonovan

Mit Python 3.6 und höher können Sie formatierte String-Literale verwenden, die auch als F-Strings bezeichnet werden. Diese sind effizienter als str.format. Darüber hinaus können Sie anstelle von math.floor eine effizientere Bodenteilung verwenden. Meiner Meinung nach ist die Syntax auch lesbarer.

Beide Methoden sind nachstehend zum Vergleich aufgeführt.

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