在整数中添加逗号的最简单方法是什么?

38
4个回答

103

迄今为止没有人提到新版Python 2.7中添加的','选项,该选项是在 格式规范微语言(Format Specification Mini-Language)中添加的。请参见PEP 378:千位分隔符格式规范器,文档位于Python 2.7版本更新内容文档中。使用它很容易,因为您不必操心locale问题,但由于这个原因,它对国际化的支持有限,详见原始 PEP 378。它可以用于浮点数、整数和小数——以及微语言规范中提供的所有其他格式化特性。

示例用法:

print format(1234, ",d")    # -> 1,234
print "{:,d}".format(1234)  # -> 1,234
print(f'{1234:,d}')         # -> 1,234 (Python 3.6+)

注意: 虽然这个新功能非常方便,但事实上使用locale模块并不比其他人建议的方法更难。优点在于,当输出数字、日期和时间等内容时,可以自动遵循各个国家使用的正确的千分位分隔符约定。此外,很容易将计算机的默认设置生效,而无需学习一堆语言和国家代码。你需要做的只是:

import locale
locale.setlocale(locale.LC_ALL, '')  # empty string for platform's default settings

在这样做之后,您可以只使用通用的'n'类型代码来输出数字(整数和浮点数)。在我的地方,逗号被用作千位分隔符,所以在设置上面显示的区域设置后,会发生以下情况:

print format(1234, "n")    # -> 1,234
print "{:n}".format(1234)  # -> 1,234

世界上许多其他地方在此情况下使用句点而不是逗号,因此在许多位置设置默认语言环境(或在setlocale()调用中明确指定此类区域的代码)会产生以下结果:

print format(1234, "n")    # -> 1.234
print "{:n}".format(1234)  # -> 1.234
'd'',d' 格式化类型说明符输出的结果不受使用(或不使用)setlocale() 的影响。但是,如果您改用locale.format()locale.format_string()函数,则会影响'd'说明符的输出。

3
很遗憾,这段代码“broken”,它延续了 locale 模块的过时特性--它不能正确地处理 Unicode。在千位分隔符是不间断空格的语言环境(例如法语、俄语)中尝试使用 format(1234, u"n"),你将得到一个新手最喜欢的异常:UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 ... - John Machin
1
@John Machin:记录一下,大多数赞是在我添加有关使用“locale”的注释之前给出的这个答案--为了让大家明白,目前正确的方法是以区域设置特定的方式进行操作,以处理Unicode?谢谢。 - martineau
(1) 点赞的时间有什么关联吗? (2) 没有Python-2.X支持的启示,只有一个丑陋的解决方法:format(1234, "n").decode(locale.getpreferredencoding()) :-( - John Machin
8
好的,在Python 2.x中使用locale对Unicode字符串无效。这是我的错误(尽管我从未声称它有效)。如果将区域设置为法语,则format(1234,“n”)的结果为1 234,并且不会引发任何异常。你的问题是:为什么你没有对其他回答中建议使用locale作为主要答案的回答进行点赞或至少发表评论? - martineau
"{,}格式化也适用于浮点数:例如'{:,.2f}'.format(mydollars)格式化为美元和美分。" - fantabolous
@fantabolous:这正是我所说的“它适用于浮点数、整数和小数——以及迷你语言规范中提供的所有其他格式特性”(已加重强调)。 - martineau

13

不要忘记为可选的“grouping”参数指定一个True值,例如locale.format(u'%d', 1234, True)。显然,locale在处理Unicode方面并不完全无能(正如@John Machin在另一个答案中的评论所暗示的那样)。 - martineau

12

这段内容从 webpyutils.py 中提取:

def commify(n):
    """
    Add commas to an integer `n`.

        >>> commify(1)
        '1'
        >>> commify(123)
        '123'
        >>> commify(1234)
        '1,234'
        >>> commify(1234567890)
        '1,234,567,890'
        >>> commify(123.0)
        '123.0'
        >>> commify(1234.5)
        '1,234.5'
        >>> commify(1234.56789)
        '1,234.56789'
        >>> commify('%.2f' % 1234.5)
        '1,234.50'
        >>> commify(None)
        >>>

    """
    if n is None: return None
    n = str(n)
    if '.' in n:
        dollars, cents = n.split('.')
    else:
        dollars, cents = n, None

    r = []
    for i, c in enumerate(str(dollars)[::-1]):
        if i and (not (i % 3)):
            r.insert(0, ',')
        r.insert(0, c)
    out = ''.join(r)
    if cents:
        out += '.' + cents
    return out

这里还有其他解决方案


2
尽管有文档字符串,但看起来它处理浮点数和整数数字都很好。变量名“dollars”和“cents”的使用,除了有点过于应用程序中心化外,似乎支持这个假设。非常适用于Python版本,如所示,将适用于2.3版本,如果enumerate()迭代器被替换为等效的内容,则可以一直使用到2.0版本。 - martineau
2
对于Python 2.4+,str(dollars)[::-1] 可以替换为更易读的 reversed(str(dollars)) - martineau
@martineau 很好的评论,我在使用Google App Engine时使用了这个函数,因为Python默认只支持2.5版本。 - systempuntoout
这个程序对负数不起作用:-123,456.00。 - fileoffset
在枚举之前,美元难道不已经是一个字符串了吗? - letmutx
真棒的函数,谢谢。 - Marko Bajlovic

5

使用locale.format()对整数进行格式化,但要注意您环境中的当前语言环境。一些环境可能没有设置或设置为不会给您逗号分隔结果的内容。

以下是我编写的代码,用于处理此问题。它将根据您的平台自动设置语言环境:

try:
    locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') #use locale.format for commafication
except locale.Error:
    locale.setlocale(locale.LC_ALL, '') #set to default locale (works on windows)

score = locale.format('%d', player['score'], True)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接