V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
coolair
V2EX  ›  问与答

Python 格式化数字,最多保留两位小数点,小数点末尾为 0 则删除,怎么写好?

  •  
  •   coolair · 2021-10-29 09:59:37 +08:00 · 2097 次点击
    这是一个创建于 1125 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前是这么写的,格式化了两遍,有更好的写法吗?

    >>> f"{float(f'{3.100:.2f}'):g}"
    '3.1'
    >>> f"{float(f'{3.104:.2f}'):g}"
    '3.1'
    >>> f"{float(f'{3.134:.2f}'):g}"
    '3.13'
    
    34 条回复    2021-10-30 10:14:49 +08:00
    bankroft
        1
    bankroft  
       2021-10-29 10:01:40 +08:00
    round(x, 2)
    coolair
        2
    coolair  
    OP
       2021-10-29 10:10:37 +08:00
    @bankroft 这样不行哦

    >>> round(3.00, 2)
    3.0
    iBaoger
        3
    iBaoger  
       2021-10-29 10:28:21 +08:00 via Android
    浮点型可能满足不了这个操作,转换为字符串处理
    ulosggs
        4
    ulosggs  
       2021-10-29 10:28:54 +08:00
    粗暴点 ('%.2f' % value).rstrip('0')
    coolair
        5
    coolair  
    OP
       2021-10-29 10:32:04 +08:00
    @ulosggs

    >>> ('%.2f' % 10.00).rstrip('0')
    '10.'
    zjj19950716
        6
    zjj19950716  
       2021-10-29 10:35:09 +08:00
    @ulosggs $ python3 -c "print(('%.2f' % 3).rstrip('0'))"
    3.
    zpfhbyx
        7
    zpfhbyx  
       2021-10-29 10:38:13 +08:00
    我寻思 直接 %.2f 就行了啊
    zpfhbyx
        8
    zpfhbyx  
       2021-10-29 10:38:36 +08:00
    啊哦 末位删除..忽略
    wangchonglie
        9
    wangchonglie  
       2021-10-29 11:13:31 +08:00
    请问正文里的 :g 有什么作用呢?
    krixaar
        10
    krixaar  
       2021-10-29 11:25:57 +08:00
    @coolair #5 那就再接着.rstrip('.')!
    ksc010
        11
    ksc010  
       2021-10-29 11:30:41 +08:00
    @krixaar 哈哈 那不如直接 rstrip('.0')
    Ediacaran
        12
    Ediacaran  
       2021-10-29 11:42:50 +08:00 via iPhone
    ‘{:g}’.format(round(f, 2))
    ericls
        13
    ericls  
       2021-10-29 11:49:53 +08:00
    '.'.join(str(int(i)) for i in divmod(num * 100, 100) if i)
    ericls
        14
    ericls  
       2021-10-29 11:52:33 +08:00
    呃 不对
    ipwx
        15
    ipwx  
       2021-10-29 12:11:50 +08:00
    就不能多写一个函数吗。。。


    def format_num(v):
    ....s = f'{v:.2f}'
    ....if '.' in s:
    ........s = s.rstrip('0')
    ....return s
    ipwx
        16
    ipwx  
       2021-10-29 12:12:43 +08:00
    In [3]: def format_num(v):
    ...: s = f'{v:.2f}'
    ...: if '.' in s:
    ...: s = s.rstrip('0').rstrip('.')
    ...: return s
    ...:

    In [4]: format_num(100)
    Out[4]: '100'

    In [5]: format_num(100.1)
    Out[5]: '100.1'

    In [6]: format_num(100.15)
    Out[6]: '100.15'

    In [7]: format_num(100.159)
    Out[7]: '100.16'
    ipwx
        17
    ipwx  
       2021-10-29 12:13:00 +08:00
    记得 rstrip('0') 以后再 rstrip('.')
    dicc
        18
    dicc  
       2021-10-29 12:14:27 +08:00
    就 rstrip('.0')
    GTim
        19
    GTim  
       2021-10-29 12:22:05 +08:00
    @dicc 你这样会把 10.00 中的直接变成 1
    coolair
        20
    coolair  
    OP
       2021-10-29 12:30:46 +08:00
    @wangchonglie 删除后面的 0
    TrembleBeforeMe
        21
    TrembleBeforeMe  
       2021-10-29 13:04:22 +08:00
    ```
    >>> float(str(float(3.104))[:4])
    3.1
    >>> float(str(float(3.134))[:4])
    3.13
    >>> float(str(float(3.100))[:4])
    3.1
    >>>
    ```
    CEBBCAT
        22
    CEBBCAT  
       2021-10-29 13:10:20 +08:00
    import math; print("{:g}".format(math.pi-math.pi%0.01))
    CEBBCAT
        23
    CEBBCAT  
       2021-10-29 13:12:18 +08:00
    ipwx
        24
    ipwx  
       2021-10-29 13:15:16 +08:00
    @CEBBCAT 这个不行,因为 %g 会用科学记数法。

    In [4]: v = 1234567890.1234

    In [5]: f'{v - v % 0.01:g}'
    Out[5]: '1.23457e+09'
    ipwx
        25
    ipwx  
       2021-10-29 13:16:29 +08:00
    @CEBBCAT 而且 v- v%0.01 这种写法也太恶臭了,明明可以 round(v, 2)
    CEBBCAT
        26
    CEBBCAT  
       2021-10-29 13:23:37 +08:00 via Android
    @ipwx 咳咳,饶我狗命,我只是想起来了记忆深处的 CPP 代码,像替换 round 这种操作,可以放在问题解决后再优化
    princelai
        27
    princelai  
       2021-10-29 14:49:06 +08:00
    换成字符串上正则

    pat = re.compile("\d+.*?(?=(\.0+$)|(0*$))")

    num = [3.000,3.1000,3.061000,3.14159]
    for n in num:
    ____print(pat.search(f"{round(n,2)}").group(0))
    cloudfox
        28
    cloudfox  
       2021-10-29 15:37:17 +08:00
    正则的话"\.?0+$"就好了
    JeffGe
        29
    JeffGe  
       2021-10-29 15:59:28 +08:00 via Android
    你这个需求有点奇怪,工程上 3.1 和 3.10 不等价,3.10 有效数字更多,去掉后都改变原数的精度了。所以我猜原生优雅的写法是没有的,我觉得上面单独写个函数先 round 两位再处理字符串的写法就可以了,正则或者自己写逻辑处理都行,考虑科学计数法那就 split('e'),处理 [0],再 'e'.join 回去。
    dicc
        30
    dicc  
       2021-10-29 17:44:48 +08:00
    @GTim 666666
    bomb77
        31
    bomb77  
       2021-10-29 17:46:04 +08:00
    str(round(3.00000, 2)).rstrip('.0')
    sugar2845
        32
    sugar2845  
       2021-10-30 01:11:31 +08:00
    @dicc 用 removesuffix ?
    c0xt30a
        33
    c0xt30a  
       2021-10-30 05:57:33 +08:00
    打个表吧,后两位才 100 中情形,枚举出来就完了
    dicc
        34
    dicc  
       2021-10-30 10:14:49 +08:00
    @sugar2845
    @bomb77 17 楼正解
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3347 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 12:04 · PVG 20:04 · LAX 04:04 · JFK 07:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.