42

我查看了标准库和 StackOverflow,并没有找到类似的问题。那么,有没有办法在不滚动我自己的功能的情况下执行以下操作?如果有人在没有内置方法的情况下编写了一个漂亮的函数,则可以加分。

def stringPercentToFloat(stringPercent)
    # ???
    return floatPercent

p1 = "99%"
p2 = "99.5%"
print stringPercentToFloat(p1)
print stringPercentToFloat(p2)

>>>> 0.99
>>>> 0.995
4

6 回答 6

80

使用strip('%'), 作为:

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
于 2012-09-14T22:18:10.463 回答
19
float(stringPercent.strip('%')) / 100.0
于 2012-09-14T22:18:47.343 回答
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:])

解释

  1. 从末尾去掉“%”。
  2. 如果 percent 没有“.”,只需将其除以 100 即可返回。
  3. 如果百分比是负数,去掉“-”并重新调用函数,然后将结果转换回负数并返回。
  4. 去掉小数位。
  5. 将(小数点所在的索引)减i2,因为我们要将小数点左移 2 个空格。
  6. 如果i是负数,那么我们需要用零填充。
    • 示例:假设输入为“1.33%”。为了能够将小数位向左移动 2 个空格,我们需要用零填充。
  7. 转换为浮点数。

测试用例(在线试用):

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)
于 2018-01-29T06:51:36.437 回答
2

只需 在解析之前将% by 替换为:e-2float

float("99.5%".replace('%', 'e-2'))

它更安全,因为如果没有%使用,结果仍然是正确的。

于 2021-09-24T01:21:05.507 回答
1

其他方式: float(stringPercent[:-1]) / 100

于 2014-07-17T06:25:29.503 回答
1

根据@WKPlus 的回答,该解决方案考虑了小数点为点.或逗号的语言环境,

float("-3,5%".replace(',','.')[:-1]) / 100
于 2020-06-16T19:10:19.757 回答