如何使用逗号作为千位分隔符打印数字?

Eli*_*ria 669 python number-formatting

我试图在Python 2.6.1中使用逗号作为千位分隔符打印一个整数.例如,我想将数字显示12345671,234,567.我该怎么做呢?我在Google上看过很多例子,但我正在寻找最简单实用的方法.

它不需要特定于语言环境来决定句点和逗号.我希望尽可能简单的事情.

小智 1614

对于Python≥2.7:

'{:,}'.format(value)  # For Python ?2.7
f'{value:,}'  # For Python ?3.7
Run Code Online (Sandbox Code Playgroud)

格式规范迷你语言,

','选项表示使用逗号表示千位分隔符.对于区域设置感知分隔符,请改用'n'整数表示类型.

  • 请注意,这在美国以外的其他地方并不正确,在这种情况下,所选的locale.format()是正确的答案. (22认同)
  • 稍微简洁一点:`format(value,',')` (12认同)
  • 在python 3.6及更高版本中,f-strings增加了更多便利.例如`f"{2**64 - 1:,}"` (10认同)
  • 关键字参数形式:`{val:,}.format(val = val)` (9认同)
  • 十分感谢.对于金额,有2位小数 - "{:,.2f}".格式(值) (8认同)
  • 对于葡萄牙,我们使用点(.)作为分隔符:{:,}".format(value).replace(',','.') (3认同)
  • 区域设置感知版本如何工作?(使用'n'整数表示类型) (3认同)
  • @wjandrea:确实如此。然而,[格式化文档](https://docs.python.org/3/library/string.html#format-specification-mini-language)的一个缺陷(IMO)是它只说“n” '` 表示类型使用 **当前语言环境设置**,但忽略了这样一个事实:**默认语言环境设置** 是可移植的 'C' 语言环境,除非事先显式调用了 'setlocale()' —即使只是使用“setlocale(LC_ALL, '')”——将其设置为其他内容(即标准 POSIX 程序行为)。 (3认同)

Mik*_*one 282

我得到了这个工作:

>>> import locale
>>> locale.setlocale(locale.LC_ALL, 'en_US')
'en_US'
>>> locale.format("%d", 1255000, grouping=True)
'1,255,000'
Run Code Online (Sandbox Code Playgroud)

当然,您不需要国际化支持,但它清晰,简洁,并使用内置库.

PS"%d"是通常的%式格式化程序.您可以只有一个格式化程序,但它可以是字段宽度和精度设置方面的任何需要.

PPS如果你不能locale上班,我建议马克答案的修改版本:

def intWithCommas(x):
    if type(x) not in [type(0), type(0L)]:
        raise TypeError("Parameter must be an integer.")
    if x < 0:
        return '-' + intWithCommas(-x)
    result = ''
    while x >= 1000:
        x, r = divmod(x, 1000)
        result = ",%03d%s" % (r, result)
    return "%d%s" % (x, result)
Run Code Online (Sandbox Code Playgroud)

递归对于负面情况很有用,但每个逗号的一次递归对我来说似乎有些过分.

  • 试试这个:locale.setlocale(locale.LC_ALL,'')它对我有用 (24认同)
  • 我尝试了你的代码,不幸的是,我得到了这个:"locale.Error:不支持的语言环境设置".:-s (14认同)
  • Mark:如果您使用的是Linux,那么您可能需要查看/etc/locale.gen中的内容,或者glibc用于构建其语言环境的内容.您可能还想尝试""en","en_US.utf8","en_US.UTF-8","en_UK"(sp?)等.迈克兹:需要一本书:"PEP博士:或者我是如何学会停止担心和爱的docs.python.org." 我放弃了回忆Python 1.5.6的所有库.对于`locale`,我尽量少用它. (11认同)
  • 你可以使用''for`setlocale`来使用默认值,希望这是合适的. (10认同)

Kas*_*ham 118

由于效率低下和不可读性,很难被击败:

>>> import itertools
>>> s = '-1234567'
>>> ','.join(["%s%s%s" % (x[0], x[1] or '', x[2] or '') for x in itertools.izip_longest(s[::-1][::3], s[::-1][1::3], s[::-1][2::3])])[::-1].replace('-,','-')
Run Code Online (Sandbox Code Playgroud)

  • 投票选出最无效且难以理解的方法来回答这个问题. (147认同)
  • 为了使这个函数我建议:`lambda x :( lambda s:','.join(["%s%s%s"%(x [0],x [1]或'',x [2 ]或'')for for itertools.izip_longest(s [:: - 1] [:: 3],s [:: - 1] [1 :: 3],s [:: - 1] [2 :: 3])])[:: - 1] .replace(' - ,',' - '))(str(x))`只是为了保持混淆主题. (10认同)
  • 期?这甚至都不可能,霍尔姆斯.这件垃圾完全忽略了当地的情况.我想知道你是如何得到这个结果的.正如预期的那样,你的例子为我生成'17,371,830'. (5认同)
  • 如果这至少能起作用就好了。尝试这个数字“17371830”它变成“173.718.3.0”=) (3认同)

Nad*_*mli 93

以下是删除不相关部分并稍微清理后的区域设置分组代码:

(以下仅适用于整数)

def group(number):
    s = '%d' % number
    groups = []
    while s and s[-1].isdigit():
        groups.append(s[-3:])
        s = s[:-3]
    return s + ','.join(reversed(groups))

>>> group(-23432432434.34)
'-23,432,432,434'
Run Code Online (Sandbox Code Playgroud)

这里已经有了一些很好的答案.我只想添加它以供将来参考.在python 2.7中,将有一个千位分隔符的格式说明符.根据python docs,它的工作原理如下

>>> '{:20,.2f}'.format(f)
'18,446,744,073,709,551,616.00'
Run Code Online (Sandbox Code Playgroud)

在python3.1中你可以这样做:

>>> format(1234567, ',d')
'1,234,567'
Run Code Online (Sandbox Code Playgroud)

  • 当然“format(1234567, ',')”是最简单的答案。 (3认同)
  • 如何用格式字符串表达这个?"%,d"%1234567不起作用 (2认同)

Emi*_*röm 72

我很惊讶没有人提到你可以用Python 3.6中的f字符串做到这一点就像这样简单:

>>> num = 10000000
>>> print(f"{num:,d}")
10,000,000
Run Code Online (Sandbox Code Playgroud)

...冒号后面的部分是格式说明符.逗号是您想要的分隔符,因此f"{num:_d}"使用下划线而不是逗号.

这相当于使用format(num, ",d")旧版本的python 3.

  • 这比任何投票较高的答案都更容易,并且不需要额外的导入。 (7认同)
  • 有时我会向下滚动一些问题。当我找到这样的宝石时,我知道这是值得的。 (5认同)
  • 这是最好也是最简单的答案。 (3认同)
  • @Hills:只能使用 , 和 _ 与此方法(上面更新)。详细信息如下:https://realpython.com/python-formatted-output/#the-group-subcomponent (2认同)

Dan*_*nov 37

这是一个单行正则表达式替换:

re.sub("(\d)(?=(\d{3})+(?!\d))", r"\1,", "%d" % val)
Run Code Online (Sandbox Code Playgroud)

仅适用于非常规输出:

import re
val = 1234567890
re.sub("(\d)(?=(\d{3})+(?!\d))", r"\1,", "%d" % val)
# Returns: '1,234,567,890'

val = 1234567890.1234567890
# Returns: '1,234,567,890'
Run Code Online (Sandbox Code Playgroud)

或者对于少于4位数的浮点数,请将格式说明符更改为%.3f:

re.sub("(\d)(?=(\d{3})+(?!\d))", r"\1,", "%.3f" % val)
# Returns: '1,234,567,890.123'
Run Code Online (Sandbox Code Playgroud)

注意:如果超过三位小数,则无法正常工作,因为它会尝试对小数部分进行分组:

re.sub("(\d)(?=(\d{3})+(?!\d))", r"\1,", "%.5f" % val)
# Returns: '1,234,567,890.12,346'
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

让我们分解一下:

re.sub(pattern, repl, string)

pattern = \
    "(\d)           # Find one digit...
     (?=            # that is followed by...
         (\d{3})+   # one or more groups of three digits...
         (?!\d)     # which are not followed by any more digits.
     )",

repl = \
    r"\1,",         # Replace that one digit by itself, followed by a comma,
                    # and continue looking for more matches later in the string.
                    # (re.sub() replaces all matches it finds in the input)

string = \
    "%d" % val      # Format the string as a decimal to begin with
Run Code Online (Sandbox Code Playgroud)


elP*_*tor 25

这就是我为花车做的事情.虽然,老实说,我不确定它适用于哪个版本 - 我使用的是2.7:

my_number = 4385893.382939491

my_string = '{:0,.2f}'.format(my_number)
Run Code Online (Sandbox Code Playgroud)

返回:4,385,893.38

更新:我最近遇到了这种格式的问题(无法告诉您具体原因),但能够通过删除以下内容来修复它0:

my_string = '{:,.2f}'.format(my_number)
Run Code Online (Sandbox Code Playgroud)


小智 19

您还可以使用'{:n}'.format( value )区域设置表示.我认为这是区域设置解决方案最简单的方法.

有关更多信息,请thousandsPython DOC中搜索.

对于货币,您可以使用locale.currency,设置标志grouping:

import locale

locale.setlocale( locale.LC_ALL, '' )
locale.currency( 1234567.89, grouping = True )
Run Code Online (Sandbox Code Playgroud)

产量

'Portuguese_Brazil.1252'
'R$ 1.234.567,89'
Run Code Online (Sandbox Code Playgroud)


lee*_*emm 19

最简单的答案:

format(123456, ",")
Run Code Online (Sandbox Code Playgroud)

结果:

'123,456'
Run Code Online (Sandbox Code Playgroud)


小智 16

以下是一些格式化方法(与浮点数和整数兼容)

num = 2437.68

# Way 1: String Formatting

'{:,}'.format(num)
>>> '2,437.68'


# Way 2: F-Strings

f'{num:,}'
>>> '2,437.68'


# Way 3: Built-in Format Function

format(num, ',')
>>> '2,437.68'
Run Code Online (Sandbox Code Playgroud)


Mar*_*ers 11

我确信必须有一个标准的库函数,但尝试使用递归自己编写它很有趣所以这就是我想出的:

def intToStringWithCommas(x):
    if type(x) is not int and type(x) is not long:
        raise TypeError("Not an integer!")
    if x < 0:
        return '-' + intToStringWithCommas(-x)
    elif x < 1000:
        return str(x)
    else:
        return intToStringWithCommas(x / 1000) + ',' + '%03d' % (x % 1000)
Run Code Online (Sandbox Code Playgroud)

话虽如此,如果其他人确实找到了标准的方法,你应该使用它.


Mar*_*oma 10

略微扩大Ian Schneider的答案:

如果要使用自定义千位分隔符,最简单的解决方案是:

'{:,}'.format(value).replace(',', your_custom_thousands_separator)
Run Code Online (Sandbox Code Playgroud)

例子

'{:,.2f}'.format(123456789.012345).replace(',', ' ')
Run Code Online (Sandbox Code Playgroud)

如果你想要这样的德语表示,它会变得有点复杂:

('{:,.2f}'.format(123456789.012345)
          .replace(',', ' ')  # 'save' the thousands separators 
          .replace('.', ',')  # dot to comma
          .replace(' ', '.')) # thousand separators to dot
Run Code Online (Sandbox Code Playgroud)


Tom*_*ner 8

评论到activestate recipe 498181重写了这个:

import re
def thous(x, sep=',', dot='.'):
    num, _, frac = str(x).partition(dot)
    num = re.sub(r'(\d{3})(?=\d)', r'\1'+sep, num[::-1])[::-1]
    if frac:
        num += dot + frac
    return num
Run Code Online (Sandbox Code Playgroud)

它使用正则表达式功能:lookahead(?=\d)确保只有三个数字的组有一个'after'后面的数字才能得到一个逗号.我说'之后'因为此时字符串是反向的.

[::-1] 只是反转一个字符串.


Mag*_*ova 8

接受的答案很好,但实际上我更喜欢format(number,',').我更容易理解和记忆.

https://docs.python.org/3/library/functions.html#format


Ada*_*rrh 7

Python 3

-

整数(不带小数):

"{:,d}".format(1234567)

-

浮点数(带小数):

"{:,.2f}".format(1234567)

其中number之前f指定小数位数.

-

奖金

印度lakhs/crores编号系统(12,34,567)的快速启动功能:

/sf/answers/3138256901/


小智 6

从 Python 2.6 版开始,您可以执行以下操作:

def format_builtin(n):
    return format(n, ',')
Run Code Online (Sandbox Code Playgroud)

对于 Python 版本 < 2.6,仅供参考,这里有 2 个手动解决方案,它们将浮点数转换为整数,但负数可以正常工作:

def format_number_using_lists(number):
    string = '%d' % number
    result_list = list(string)
    indexes = range(len(string))
    for index in indexes[::-3][1:]:
        if result_list[index] != '-':
            result_list.insert(index+1, ',')
    return ''.join(result_list)
Run Code Online (Sandbox Code Playgroud)

这里有几点需要注意:

  • 这一行:string = '%d' % number漂亮地将数字转换为字符串,它支持负数并从浮点数中删除分数,使它们成为整数;
  • 这个切片索引 [::-3]返回从末尾开始的每第三个项目,所以我使用另一个切片[1:]来删除最后一个项目,因为我不需要在最后一个数字后面加逗号;
  • 这个条件如果 l[index] != '-'被用来支持负数,不要在减号后插入逗号。

还有一个更硬核的版本:

def format_number_using_generators_and_list_comprehensions(number):
    string = '%d' % number
    generator = reversed( 
        [
            value+',' if (index!=0 and value!='-' and index%3==0) else value
            for index,value in enumerate(reversed(string))
        ]
    )
    return ''.join(generator)
Run Code Online (Sandbox Code Playgroud)