【问题标题】:How can I print a float with thousands separators?如何打印带有数千个分隔符的浮点数?
【发布时间】:2012-10-16 11:09:30
【问题描述】:

如何格式化十进制数,使32757121.33 显示为32.757.121,33

【问题讨论】:

  • @AshwiniChaudhary 在德国,原版海报格式正常。

标签: python format decimal


【解决方案1】:
>>> import locale

>>> locale.setlocale(locale.LC_ALL, 'en_GB.UTF-8')
'en_GB.UTF-8'
>>> print(locale.format_string('%.2f', 12742126.15, True))
12,742,126.15

此示例代码适用于 docker 容器中的 GB。

FROM python:3.8.2-slim-buster

RUN apt-get update && apt-get install -y locales && \
    sed -i -e 's/# en_GB.UTF-8 UTF-8/en_GB.UTF-8 UTF-8/' /etc/locale.gen && \
    dpkg-reconfigure --frontend=noninteractive locales

ENV LANG en_GB.UTF-8
ENV LC_ALL en_GB.UTF-8

可以通过在终端 (Linux Dirstro) 上运行以下命令来找到语言环境

locale -a

然后出现完整的语言环境列表:

en_AG.utf8
en_AU.utf8
...
en_GB.utf8
...

【讨论】:

    【解决方案2】:

    我找到了另一个解决方案:

    '{:,.2f}'.format(num).replace(".","%").replace(",",".").replace("%",",")
    

    【讨论】:

    • 糟糕的解决方案。如果在数千个任意长度的字符串上调用它会怎样?
    • 这在...(num)之后没有任何废话。
    • 漂亮的解决方案,让编译器完成他们的工作:)
    • 是的,这很糟糕,我现在看着它笑了。但它在 2012 年起作用了:D
    【解决方案3】:

    如果由于某种原因不能或不想使用locale,也可以使用正则表达式:

    import re
    def sep(s, thou=",", dec="."):
        integer, decimal = s.split(".")
        integer = re.sub(r"\B(?=(?:\d{3})+$)", thou, integer)
        return integer + dec + decimal
    

    sep() 采用标准 Python 浮点数的字符串表示形式,并使用自定义的千位和小数分隔符返回它。

    >>> s = "%.2f" % 32757121.33
    >>> sep(s)
    '32,757,121.33'
    >>> sep(s, thou=".", dec=",")
    '32.757.121,33'
    

    说明:

    \B      # Assert that we're not at the start of the number
    (?=     # Match at a position where it's possible to match...
     (?:    #  the following regex:
      \d{3} #   3 digits
     )+     #  repeated at least once
     $      #  until the end of the string
    )       # (thereby ensuring a number of digits divisible by 3
    

    【讨论】:

    • 非常感谢!如果你有兴趣,我也发现了这个变种 '{:20,.2f}'.format(num).replace(".","%").replace(",",".").replace ("%",",")
    • 当你可以使用verbose时为什么要创建解释部分。
    【解决方案4】:

    使用locale.format():

    >>> import locale
    >>> locale.setlocale(locale.LC_ALL, 'German')
    'German_Germany.1252'
    >>> print(locale.format('%.2f', 32757121.33, True))
    32.757.121,33
    

    您可以将区域设置更改限制为显示数值(使用 locale.format()locale.str() 等时),而其他区域设置不受影响:

    >>> locale.setlocale(locale.LC_NUMERIC, 'English')
    'English_United States.1252'
    >>> print(locale.format('%.2f', 32757121.33, True))
    32,757,121.33
    >>> locale.setlocale(locale.LC_NUMERIC, 'German')
    'German_Germany.1252'
    >>> print(locale.format('%.2f', 32757121.33, True))
    32.757.121,33
    

    【讨论】:

    • 这些调用依赖于操作系统可用的语言环境带来了额外的痛苦。 - 此外,语言环境名称会因不同的操作系统而异。甚至是不同的 Linux 发行版(这意味着您必须在生产服务器上对此进行测试,或者拥有提供后备的代码,直到找到现有的语言环境)
    • @jsbueno:好点。文档还指出 setlocale() 不是线程安全的,并且还有其他一些问题,尤其是在大型、多模块程序中使用时,因此阅读文档很重要。在一个小程序中,这可以说没有那么重要。此外,还有其他语言环境名称,如en_ENde_DE,可能比German 等更通用;不过,我还没有找到允许的区域设置列表。
    • 所以我遇到了这样一个问题,即:“渲染时出现错误:不支持的语言环境设置”我尝试了不同的变体(德语、德语、de_DE 等)。我可以在没有语言环境的情况下做到吗?使用 inly 格式?
    • 你在什么平台上运行程序?
    • 问题在于它不是线程安全的,并且假定开发人员希望在程序中的任何地方都获得相同的效果(除非可以不断地来回切换,这很骇人听闻)。应该有一种方法可以在给定语言环境中获取格式化的值,而无需将整个运行时平台设置为该语言环境。比如,locale.format(format_string, value, locale) - 唉,这些似乎都没有。
    猜你喜欢
    • 2013-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-06
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多