【问题标题】:Convert String to Float (Currency) but has more than one decimal points [duplicate]将字符串转换为浮点数(货币),但小数点多于一位 [重复]
【发布时间】:2023-03-25 01:18:01
【问题描述】:

所以我在网上抓取 Foot locker 网站,现在当我得到价格时,我得到的价格超过小数点。

我想把它四舍五入到小数点后两位,我该怎么做?

我的价目表:

90.00
170.00
198.00
137.99137.99158.00

当我尝试浮动功能/方法时出现错误,有人可以帮忙吗:)

print(float(Price))

90.0
170.0
198.0

ValueError: could not convert string to float: '137.99137.99158.00'

我也想把它四舍五入到小数点后两位,所以 90.0 会变成 90.00 :)

【问题讨论】:

标签: python python-3.x function floating-point numbers


【解决方案1】:

再次查看您的价格后,在我看来,多个小数点的问题是由于价格之间缺少空格。也许网络爬虫需要修复?如果你想继续你所拥有的,你可以用正则表达式来做。但我的解决方法只有在价格总是以两位小数给出时才有效。

import re

list_prices = [ '90.00', '170.00', '198.00',  '137.99137.99158.00' ]

pattern_price = re.compile(r'[0-9]+\.[0-9]{2}')
list_prices_clean = pattern_price.findall('\n'.join(list_prices))
print(list_prices_clean)

# ['90.00', '170.00', '198.00', '137.99', '137.99', '158.00']

【讨论】:

    【解决方案2】:

    您收到该错误是因为输入 137.99137.99158.00 不是 float 函数的有效输入。我编写了以下函数来清理您的输入。

    def clean_invalid_number(num):
        split_num = num.split('.')
        num_len = len(split_num)
        if len(split_num) > 1:
            temp = split_num[0] + '.'
            for i in range(1,num_len):
                temp += split_num[i]
            return temp
        else:
            return num
    

    为了解释上述内容,我使用了返回列表的split 函数。如果列表长度大于 1,则有超过 1 个句号,这意味着需要清理数据。列表不包含您拆分的字符。

    至于返回 2 个小数点只需使用

    Price = round(Price,2)

    如果要转换为浮点数,则返回两个 90.00 而不是 90.0 没有意义。

    这是完整的演示代码:

    prices = ['90.00', '170.00', '198.00', '137.99137.99158.00']
    
    prices = [round(float(clean_invalid_number(p)),2 ) for p in prices]
    
    print(prices)
    
    [90.0, 170.0, 198.0, 137.99]
    
    
    

    【讨论】:

      【解决方案3】:
      1. 用临时分隔符替换第一个点
      2. 删除所有其他点
      3. 用点替换临时分隔符
      4. 圆形
      5. 使用两位小数打印

      像这样:

      list_prices = [ '90.00', '170.00', '198.00',  '137.99137.99158.00']
      
      def clean_price(price, sep='.'):
          price = str(price)
          price = price.replace(sep, 'DOT', 1)
          price = price.replace(sep, '')
          price = price.replace('DOT', '.')
          rounded = round(float(price),2)
          return f'{rounded:.2f}'
      
      list_prices_clean = [clean_price(price) for price in list_prices]
      
      print(list_prices_clean)
      
      # ['90.09', '170.00', '198.00', '137.99']
      

      编辑:

      如果您的意思是在最后一个小数点后四舍五入:

      def clean_price(price, sep='.'):
          price = str(price)
          num_seps = price.count(sep)
          price = price.replace(sep, '', num_seps-1)
          rounded = round(float(price),2)
          return f'{rounded:.2f}'
      
      list_prices_clean = [clean_price(price) for price in list_prices]
      
      print(list_prices_clean)
      
      # ['90.00', '170.00', '198.00', '1379913799158.00']
      

      【讨论】:

        【解决方案4】:

        无需编写自定义方法,使用正则表达式(regex)从字符串中提取模式。您的问题是长字符串 (137.99137.99158.00) 是 3 个价格,中间没有空格。正则表达式 "[0-9]+.[0-9][0-9]" 查找在 "." 之前具有一个或多个数字的所有模式。和“.”后面的两个数字

        import re           
        reg = "[0-9]+\.[0-9]{0,2}";
        test = "137.99137.99158.00";
        p = re.compile(reg);
        result = p.search(test);
        result.group(0)
        

        输出:

        137.99
        

        简短说明:

        • '[0-9]' "数字"
        • '+' "一个或多个"
        • '.' “点的字符串”

        Regex 一开始似乎很奇怪,但它是一项必不可少的技能。尤其是当您想挖掘文本时。

        【讨论】:

        • 这是一个 Python 问题,汤姆。
        • @PranavHosangadi ups,抱歉更正为 Python。但完全一样。
        • 请注意,您应该像我在第二个答案中所做的那样转义点。您的模式无意中也匹配“137991379915800”
        • @Durtal 真的,谢谢。对于点后 2 位小数的问题(在我的和您的帖子中),请考虑 [0-9]{0,2} 以允许点后有 0 或 2 位小数......不是很理想,但它会有所帮助价格
        • 如果小数点为 0,则不应有点。所以“19”不会匹配。也许我们应该用 '[0-9]+\.?[0-9]{0,2}' 声明点是可选的。但这已经超出了最初的问题。
        【解决方案5】:

        好的,我终于找到了解决问题的方法,也感谢大家的帮助

        def Price(s):
            try:
                P = s.find("div",class_="ProductPrice").text.replace("$","").strip().split("to")[1].split(".")
                return round(float(".".join(P[0:2])),2)
            except:
                P = s.find("div",class_="ProductPrice").text.replace("$","").strip().split("to")[0].split(".")
                return float(".".join(P[0:2]))
        

        【讨论】:

        • 不解释就没有任何用处。
        猜你喜欢
        • 2020-05-22
        • 2017-04-04
        • 1970-01-01
        • 2012-01-15
        • 2015-12-19
        • 2018-07-22
        • 1970-01-01
        • 2011-11-25
        相关资源
        最近更新 更多