Что такое чистый способ преобразования процентной ставки строки в float?
Я посмотрел в стандартной библиотеке и на StackOverflow и не нашел аналогичного вопроса. Итак, есть ли способ сделать следующее, не сворачивая мою собственную функцию? Бонусные очки, если кто-то пишет красивую функцию, если нет встроенного способа.
def stringPercentToFloat(stringPercent)
# ???
return floatPercent
p1 = "99%"
p2 = "99.5%"
print stringPercentToFloat(p1)
print stringPercentToFloat(p2)
>>>> 0.99
>>>> 0.995
Ответы
Ответ 1
Используйте strip('%')
, as:
In [9]: "99.5%".strip('%')
Out[9]: '99.5' #convert this to float using float() and divide by 100
In [10]: def p2f(x):
return float(x.strip('%'))/100
....:
In [12]: p2f("99%")
Out[12]: 0.98999999999999999
In [13]: p2f("99.5%")
Out[13]: 0.995
Ответ 2
float(stringPercent.strip('%')) / 100.0
Ответ 3
Другой способ:
float(stringPercent[:-1]) / 100
Ответ 4
Я написал следующий метод, который всегда должен возвращать вывод с той же точностью, что и ввод, без ошибок с плавающей запятой, как в других ответах.
def percent_to_float(s):
s = str(float(s.rstrip("%")))
i = s.find(".")
if i == -1:
return int(s) / 100
if s.startswith("-"):
return -percent_to_float(s.lstrip("-"))
s = s.replace(".", "")
i -= 2
if i < 0:
return float("." + "0" * abs(i) + s)
else:
return float(s[:i] + "." + s[i:])
Объяснение
- Снимите "%" с конца.
- Если в процентах нет ".", Просто верните его, разделенное на 100.
- Если процент отрицательный, удалите "-" и повторно вызовите функцию, затем преобразуйте результат обратно в отрицательный и верните его.
- Удалите десятичную дробь.
- Уменьшите
i
(индекс, в котором находился десятичный знак) на 2, потому что мы хотим сместить десятичное место на 2 пробела влево.
- Если
i
отрицателен, то нам нужно дополнить нулями.
- Пример: Предположим, ввод равен "1,33%". Чтобы иметь возможность сдвигать десятичную запятую на 2 пробела влево, нам нужно добавить ноль.
- Преобразовать в число с плавающей точкой.
Тестовый пример (Попробуйте онлайн):
from unittest.case import TestCase
class ParsePercentCase(TestCase):
tests = {
"150%" : 1.5,
"100%" : 1,
"99%" : 0.99,
"99.999%" : 0.99999,
"99.5%" : 0.995,
"95%" : 0.95,
"90%" : 0.9,
"50%" : 0.5,
"66.666%" : 0.66666,
"42%" : 0.42,
"20.5%" : 0.205,
"20%" : 0.2,
"10%" : 0.1,
"3.141592653589793%": 0.03141592653589793,
"1%" : 0.01,
"0.1%" : 0.001,
"0.01%" : 0.0001,
"0%" : 0,
}
tests = sorted(tests.items(), key=lambda x: -x[1])
def test_parse_percent(self):
for percent_str, expected in self.tests:
parsed = percent_to_float(percent_str)
self.assertEqual(expected, parsed, percent_str)
def test_parse_percent_negative(self):
negative_tests = [("-" + s, -f) for s, f in self.tests]
for percent_str, expected in negative_tests:
parsed = percent_to_float(percent_str)
self.assertEqual(expected, parsed, percent_str)