Как напечатать число с запятыми как разделители тысяч?



Я пытаюсь напечатать целое число в Python 2.6.1 с запятыми в качестве разделителей тысяч. Например, я хочу показать число 1234567 Как 1,234,567. Как бы я это сделал? Я видел много примеров в Google, но я ищу самый простой практический способ.



для выбора между точками и запятыми не нужно быть специфичным для локали. Я бы предпочел что-то настолько простое, насколько это возможно.

526   26  

26 ответов:

Для Python ≥ 2.7:

"{:,}".format(value)

на Формат Спецификации Мини-Язык,

The ',' опция сигнализирует об использовании запятой для разделителя тысяч. Для разделителя с учетом локали используйте 'n' целочисленный тип представления вместо этого.

я получил эту работу:

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

конечно, вы не нужно поддержка интернационализации, но это ясно, лаконично и использует встроенную библиотеку.

P. S. Что "%D" - это обычные %-стиль форматирования. Вы можете иметь только один форматер, но это может быть все, что вам нужно с точки зрения ширины поля и настройки точности.

P. P. S. Если вы не можете сделать 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)

рекурсия полезна для отрицательного случая, но одна рекурсия на запятую кажется мне немного чрезмерной.

для неэффективности и нечитабельности трудно победить:

>>> 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('-,','-')

вот код группировки локали после удаления ненужных частей и очистки его немного:

(следующий работает только для целых чисел)

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'

уже есть несколько хороших ответов здесь. Я просто хочу добавить на будущее. В Python 2.7 будет спецификатор формата для разделителя тысяч. Согласно python docs как это работает

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

в python3. 1 Вы можете сделать то же самое, как это:

>>> format(1234567, ',d')
'1,234,567'

вот замена однострочного регулярного выражения:

re.sub("(\d)(?=(\d{3})+(?!\d))", r",", "%d" % val)

работает только для выходов inegral:

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

val = 1234567890.1234567890
# Returns: '1,234,567,890'

или для поплавков с менее чем 4 цифрами измените спецификатор формата на %.3f:

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

Примечание: не работает правильно с более чем тремя десятичными цифрами, поскольку он попытается сгруппировать десятичную часть:

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

как это работает

давайте разберем его:

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",",         # 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

Я удивлен, что никто не упомянул, что вы можете сделать это с помощью f-строк в Python 3.6 так же просто, как это:

>>> num = 10000000
>>> print(f"{num:,d}")
10,000,000

... где часть после двоеточия является спецификатором формата. Запятая-это символ разделителя, который вы хотите, поэтому f"{num:_d}" использует подчеркивания вместо запятой.

Это эквивалентно использованию format(num, ",d") для более старых версий Python 3.

Это то, что я делаю для поплавков. Хотя, честно говоря, я не уверен, для каких версий он работает - я использую 2.7:

my_number = 4385893.382939491

my_string = '{:0,.2f}'.format(my_number)

возвращает: 4,385,893.38

Update: недавно у меня была проблема с этим форматом (не мог сказать вам точную причину), но смог ее исправить, отбросив 0:

my_string = '{:,.2f}'.format(my_number)

вы также можете использовать '{:n}'.format( value ) для представления языка. Я думаю, что это самый простой способ для решения локаль.

для получения дополнительной информации, поиск thousands на Python DOC.

для валюты, вы можете использовать locale.currency, установив флаг grouping:

код

import locale

locale.setlocale( locale.LC_ALL, '' )
locale.currency( 1234567.89, grouping = True )

выход

'Portuguese_Brazil.1252'
'R$ 1.234.567,89'

Я уверен, что для этого должна быть стандартная библиотечная функция, но было интересно попробовать написать ее самостоятельно с помощью рекурсии, поэтому вот что я придумал:

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)

сказав это, если кто-то еще найдет стандартный способ сделать это, вы должны использовать это вместо этого.

С комментарии чтобы активировать рецепт 498181 я переработал этот:

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

он использует функцию регулярных выражений:lookahead т. е. (?=\d) чтобы убедиться, что только группы из трех цифр, которые имеют цифры после них запятая. Я говорю "После", потому что строка в этот момент обратная.

[::-1] просто переворачивает строку.

Python 3

--

целые числа (без десятичной дроби):

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

--

поплавки (с запятой):

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

где число перед f указывает количество знаков после запятой.

--

бонус

функция быстрого и грязного стартера для индийской системы счисления lakhs / crores (12,34,567):

https://stackoverflow.com/a/44832241/4928578

из Python версии 2.6 вы можете сделать это:

def format_builtin(n):
    return format(n, ',')

для версий Python

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)

несколько вещей, чтобы заметить здесь:

  • эта строка: string = '%d ' % number красиво преобразует число в строку, поддерживает негативы и сбрасывает дроби с поплавков, делая их ints;
  • этот фрагмент индексы[::-3] возвращает каждый третий элемент, начиная с конец, поэтому я использовал еще один кусочек [1:] удалить последний элемент потому что мне не нужна запятая после последнего числа;
  • этот условный если l[индекс]!= ' - ' используется для поддержки отрицательных чисел, не вставляйте запятую после знака минус.

и более хардкорная версия:

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)

слегка расширяя ответ Яна Шнайдера:

Если вы хотите использовать пользовательский разделитель тысяч, самое простое решение:

'{:,}'.format(value).replace(',', your_custom_thousands_separator)

примеры

'{:,.2f}'.format(123456789.012345).replace(',', ' ')

Если вы хотите, чтобы немецкое представление было таким, оно становится немного сложнее:

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

принятый ответ в порядке, но я на самом деле предпочитаю format(number,','). Мне легче интерпретировать и запоминать.

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

вот тот, который работает для поплавков:

def float2comma(f):
    s = str(abs(f)) # Convert to a string
    decimalposition = s.find(".") # Look for decimal point
    if decimalposition == -1:
        decimalposition = len(s) # If no decimal, then just work from the end
    out = "" 
    for i in range(decimalposition+1, len(s)): # do the decimal
        if not (i-decimalposition-1) % 3 and i-decimalposition-1: out = out+","
        out = out+s[i]      
    if len(out):
        out = "."+out # add the decimal point if necessary
    for i in range(decimalposition-1,-1,-1): # working backwards from decimal point
        if not (decimalposition-i-1) % 3 and decimalposition-i-1: out = ","+out
        out = s[i]+out      
    if f < 0:
        out = "-"+out
    return out

Пример Использования:

>>> float2comma(10000.1111)
'10,000.111,1'
>>> float2comma(656565.122)
'656,565.122'
>>> float2comma(-656565.122)
'-656,565.122'

один лайнер для Python 2.5+ и Python 3 (только положительный int):

''.join(reversed([x + (',' if i and not i % 3 else '') for i, x in enumerate(reversed(str(1234567)))]))

Я новичок в Python, но опытный программист. У меня есть Python 3.5, поэтому я могу просто использовать запятую, но это, тем не менее, интересное упражнение по программированию. Рассмотрим случай целого числа без знака. Наиболее читаемой программой Python для добавления тысяч разделителей является:

def add_commas(instr):
    out = [instr[0]]
    for i in range(1, len(instr)):
        if (len(instr) - i) % 3 == 0:
            out.append(',')
        out.append(instr[i])
    return ''.join(out)

также можно использовать список понимание:

add_commas(instr):
    rng = reversed(range(1, len(instr) + (len(instr) - 1)//3 + 1))
    out = [',' if j%4 == 0 else instr[-(j - j//4)] for j in rng]
    return ''.join(out)

Это короче, и может быть один лайнер, но вам придется сделать некоторые умственные упражнения, чтобы понять, почему это работает. В обоих случаях мы получаем:

for i in range(1, 11):
    instr = '1234567890'[:i]
    print(instr, add_commas(instr))
1 1
12 12
123 123
1234 1,234
12345 12,345
123456 123,456
1234567 1,234,567
12345678 12,345,678
123456789 123,456,789
1234567890 1,234,567,890

первая версия является более разумным выбором, если вы хотите, чтобы программа была понятна.

это делает деньги вместе с запятыми

def format_money(money, presym='$', postsym=''):
    fmt = '%0.2f' % money
    dot = string.find(fmt, '.')
    ret = []
    if money < 0 :
        ret.append('(')
        p0 = 1
    else :
        p0 = 0
    ret.append(presym)
    p1 = (dot-p0) % 3 + p0
    while True :
        ret.append(fmt[p0:p1])
        if p1 == dot : break
        ret.append(',')
        p0 = p1
        p1 += 3
    ret.append(fmt[dot:])   # decimals
    ret.append(postsym)
    if money < 0 : ret.append(')')
    return ''.join(ret)

у меня есть python 2 и python 3 версии этого кода. Я знаю, что вопрос был задан для python 2, но теперь (8 лет спустя lol) люди, вероятно, будут использовать python 3.

Код Python 3:

import random
number = str(random.randint(1, 10000000))
comma_placement = 4
print('The original number is: {}. '.format(number))
while True:
    if len(number) % 3 == 0:
        for i in range(0, len(number) // 3 - 1):
            number = number[0:len(number) - comma_placement + 1] + ',' + number[len(number) - comma_placement + 1:]
            comma_placement = comma_placement + 4
    else:
        for i in range(0, len(number) // 3):
            number = number[0:len(number) - comma_placement + 1] + ',' + number[len(number) - comma_placement + 1:]
    break
print('The new and improved number is: {}'.format(number))        


Код Python 2: (Edit. Код python 2 не работает. Я думаю, что синтаксис разный).

import random
number = str(random.randint(1, 10000000))
comma_placement = 4
print 'The original number is: %s.' % (number)
while True:
    if len(number) % 3 == 0:
        for i in range(0, len(number) // 3 - 1):
            number = number[0:len(number) - comma_placement + 1] + ',' + number[len(number) - comma_placement + 1:]
            comma_placement = comma_placement + 4
    else:
        for i in range(0, len(number) // 3):
            number = number[0:len(number) - comma_placement + 1] + ',' + number[len(number) - comma_placement + 1:]
    break
print 'The new and improved number is: %s.' % (number) 

Я использую python 2.5, поэтому у меня нет доступа к встроенному форматированию.

Я посмотрел на код Django intcomma (intcomma_recurs в коде ниже) и понял, что это неэффективно, потому что это рекурсивно, а также компиляция регулярного выражения при каждом запуске тоже не очень хорошо. Это не обязательно "проблема", поскольку django на самом деле не ориентирован на такую низкоуровневую производительность. Кроме того, я ожидал, что в 10 раз разница в производительности, но это только 3 раза замедлившийся.

из любопытства я реализовал несколько версий intcomma, чтобы увидеть, каковы преимущества производительности при использовании regex. Мои тестовые данные заключают небольшое преимущество для этой задачи, но на удивление не так много.

Я также был рад увидеть то, что я подозревал: использование обратного подхода xrange не нужно в случае без регулярных выражений, но это делает код немного лучше за счет ~10% производительности.

кроме того, я предполагаю, что вы передача является строкой и выглядит несколько как число. Результаты не определены иначе.

from __future__ import with_statement
from contextlib import contextmanager
import re,time

re_first_num = re.compile(r"\d")
def intcomma_noregex(value):
    end_offset, start_digit, period = len(value),re_first_num.search(value).start(),value.rfind('.')
    if period == -1:
        period=end_offset
    segments,_from_index,leftover = [],0,(period-start_digit) % 3
    for _index in xrange(start_digit+3 if not leftover else start_digit+leftover,period,3):
        segments.append(value[_from_index:_index])
        _from_index=_index
    if not segments:
        return value
    segments.append(value[_from_index:])
    return ','.join(segments)

def intcomma_noregex_reversed(value):
    end_offset, start_digit, period = len(value),re_first_num.search(value).start(),value.rfind('.')
    if period == -1:
        period=end_offset
    _from_index,segments = end_offset,[]
    for _index in xrange(period-3,start_digit,-3):
        segments.append(value[_index:_from_index])
        _from_index=_index
    if not segments:
        return value
    segments.append(value[:_from_index])
    return ','.join(reversed(segments))

re_3digits = re.compile(r'(?<=\d)\d{3}(?!\d)')
def intcomma(value):
    segments,last_endoffset=[],len(value)
    while last_endoffset > 3:
        digit_group = re_3digits.search(value,0,last_endoffset)
        if not digit_group:
            break
        segments.append(value[digit_group.start():last_endoffset])
        last_endoffset=digit_group.start()
    if not segments:
        return value
    if last_endoffset:
        segments.append(value[:last_endoffset])
    return ','.join(reversed(segments))

def intcomma_recurs(value):
    """
    Converts an integer to a string containing commas every three digits.
    For example, 3000 becomes '3,000' and 45000 becomes '45,000'.
    """
    new = re.sub("^(-?\d+)(\d{3})", '\g<1>,\g<2>', str(value))
    if value == new:
        return new
    else:
        return intcomma(new)

@contextmanager
def timed(save_time_func):
    begin=time.time()
    try:
        yield
    finally:
        save_time_func(time.time()-begin)

def testset_xsimple(func):
    func('5')

def testset_simple(func):
    func('567')

def testset_onecomma(func):
    func('567890')

def testset_complex(func):
    func('-1234567.024')

def testset_average(func):
    func('-1234567.024')
    func('567')
    func('5674')

if __name__ == '__main__':
    print 'Test results:'
    for test_data in ('5','567','1234','1234.56','-253892.045'):
        for func in (intcomma,intcomma_noregex,intcomma_noregex_reversed,intcomma_recurs):
            print func.__name__,test_data,func(test_data)
    times=[]
    def overhead(x):
        pass
    for test_run in xrange(1,4):
        for func in (intcomma,intcomma_noregex,intcomma_noregex_reversed,intcomma_recurs,overhead):
            for testset in (testset_xsimple,testset_simple,testset_onecomma,testset_complex,testset_average):
                for x in xrange(1000): # prime the test
                    testset(func)
                with timed(lambda x:times.append(((test_run,func,testset),x))):
                    for x in xrange(50000):
                        testset(func)
    for (test_run,func,testset),_delta in times:
        print test_run,func.__name__,testset.__name__,_delta

и вот результаты теста:

intcomma 5 5
intcomma_noregex 5 5
intcomma_noregex_reversed 5 5
intcomma_recurs 5 5
intcomma 567 567
intcomma_noregex 567 567
intcomma_noregex_reversed 567 567
intcomma_recurs 567 567
intcomma 1234 1,234
intcomma_noregex 1234 1,234
intcomma_noregex_reversed 1234 1,234
intcomma_recurs 1234 1,234
intcomma 1234.56 1,234.56
intcomma_noregex 1234.56 1,234.56
intcomma_noregex_reversed 1234.56 1,234.56
intcomma_recurs 1234.56 1,234.56
intcomma -253892.045 -253,892.045
intcomma_noregex -253892.045 -253,892.045
intcomma_noregex_reversed -253892.045 -253,892.045
intcomma_recurs -253892.045 -253,892.045
1 intcomma testset_xsimple 0.0410001277924
1 intcomma testset_simple 0.0369999408722
1 intcomma testset_onecomma 0.213000059128
1 intcomma testset_complex 0.296000003815
1 intcomma testset_average 0.503000020981
1 intcomma_noregex testset_xsimple 0.134000062943
1 intcomma_noregex testset_simple 0.134999990463
1 intcomma_noregex testset_onecomma 0.190999984741
1 intcomma_noregex testset_complex 0.209000110626
1 intcomma_noregex testset_average 0.513000011444
1 intcomma_noregex_reversed testset_xsimple 0.124000072479
1 intcomma_noregex_reversed testset_simple 0.12700009346
1 intcomma_noregex_reversed testset_onecomma 0.230000019073
1 intcomma_noregex_reversed testset_complex 0.236999988556
1 intcomma_noregex_reversed testset_average 0.56299996376
1 intcomma_recurs testset_xsimple 0.348000049591
1 intcomma_recurs testset_simple 0.34600019455
1 intcomma_recurs testset_onecomma 0.625
1 intcomma_recurs testset_complex 0.773999929428
1 intcomma_recurs testset_average 1.6890001297
1 overhead testset_xsimple 0.0179998874664
1 overhead testset_simple 0.0190000534058
1 overhead testset_onecomma 0.0190000534058
1 overhead testset_complex 0.0190000534058
1 overhead testset_average 0.0309998989105
2 intcomma testset_xsimple 0.0360000133514
2 intcomma testset_simple 0.0369999408722
2 intcomma testset_onecomma 0.207999944687
2 intcomma testset_complex 0.302000045776
2 intcomma testset_average 0.523000001907
2 intcomma_noregex testset_xsimple 0.139999866486
2 intcomma_noregex testset_simple 0.141000032425
2 intcomma_noregex testset_onecomma 0.203999996185
2 intcomma_noregex testset_complex 0.200999975204
2 intcomma_noregex testset_average 0.523000001907
2 intcomma_noregex_reversed testset_xsimple 0.130000114441
2 intcomma_noregex_reversed testset_simple 0.129999876022
2 intcomma_noregex_reversed testset_onecomma 0.236000061035
2 intcomma_noregex_reversed testset_complex 0.241999864578
2 intcomma_noregex_reversed testset_average 0.582999944687
2 intcomma_recurs testset_xsimple 0.351000070572
2 intcomma_recurs testset_simple 0.352999925613
2 intcomma_recurs testset_onecomma 0.648999929428
2 intcomma_recurs testset_complex 0.808000087738
2 intcomma_recurs testset_average 1.81900000572
2 overhead testset_xsimple 0.0189998149872
2 overhead testset_simple 0.0189998149872
2 overhead testset_onecomma 0.0190000534058
2 overhead testset_complex 0.0179998874664
2 overhead testset_average 0.0299999713898
3 intcomma testset_xsimple 0.0360000133514
3 intcomma testset_simple 0.0360000133514
3 intcomma testset_onecomma 0.210000038147
3 intcomma testset_complex 0.305999994278
3 intcomma testset_average 0.493000030518
3 intcomma_noregex testset_xsimple 0.131999969482
3 intcomma_noregex testset_simple 0.136000156403
3 intcomma_noregex testset_onecomma 0.192999839783
3 intcomma_noregex testset_complex 0.202000141144
3 intcomma_noregex testset_average 0.509999990463
3 intcomma_noregex_reversed testset_xsimple 0.125999927521
3 intcomma_noregex_reversed testset_simple 0.126999855042
3 intcomma_noregex_reversed testset_onecomma 0.235999822617
3 intcomma_noregex_reversed testset_complex 0.243000030518
3 intcomma_noregex_reversed testset_average 0.56200003624
3 intcomma_recurs testset_xsimple 0.337000131607
3 intcomma_recurs testset_simple 0.342000007629
3 intcomma_recurs testset_onecomma 0.609999895096
3 intcomma_recurs testset_complex 0.75
3 intcomma_recurs testset_average 1.68300008774
3 overhead testset_xsimple 0.0189998149872
3 overhead testset_simple 0.018000125885
3 overhead testset_onecomma 0.018000125885
3 overhead testset_complex 0.0179998874664
3 overhead testset_average 0.0299999713898

просто подкласс long (или float, или любой другой). Это очень практично, потому что таким образом вы все еще можете использовать свои числа в math ops (и, следовательно, существующий код), но все они будут красиво печататься в вашем терминале.

>>> class number(long):

        def __init__(self, value):
            self = value

        def __repr__(self):
            s = str(self)
            l = [x for x in s if x in '1234567890']
            for x in reversed(range(len(s)-1)[::3]):
                l.insert(-x, ',')
            l = ''.join(l[1:])
            return ('-'+l if self < 0 else l) 

>>> number(-100000)
-100,000
>>> number(-100)
-100
>>> number(-12345)
-12,345
>>> number(928374)
928,374
>>> 345

итальянские числа: тысячный разделитель-это'.-

я решил это таким образом... для диктатора

from random import randint

voci = {
    "immobilizzazioni": randint(200000, 500000),
    "tfr": randint(10000, 25000),
    "ac": randint(150000, 200000),
    "fondo": randint(10500, 22350),
    "debiti": randint(150000, 250000),
    "ratei_attivi": randint(2000, 2500),
    "ratei_passivi": randint(1500, 2600),
    "crediti_v_soci": randint(10000, 30000)
}


testo_rnd2 = """Nell’azienda Hypermax S.p.a. di Bologna le immobilizzazioni valgono {immobilizzazioni:,} €, i debiti per TFR sono pari a {tfr:,} €, l’attivo circolante è di {ac:,} euro, il fondo rischi ed oneri ha un importo pari a {fondo:,} euro, i debiti sono {debiti:,} €, i ratei e risconti attivi sono pari a {ratei_attivi:,} euro, i ratei e risconti passivi sono pari a {ratei_passivi:,} euro. I crediti verso i soci sono pari a {crediti_v_soci:,} euro."""

print(testo_rnd2)

из: le immobilizzazioni valgono 419.168 €. я debiti в СКР СОНО пари в размере 13.255. l'attivo circolante è di 195.443 евро. иль-Фондо рищи Эд өнері ГА ООН импорто Альпари в 13.374 евро. I debiti sono 180.947 €. I ratei e risconti attivi sono pari a 2.271 euro. I ratei e risconti passivi sono pari a 1.864 евро. I crediti verso i soci sono pari a 17.630 евро.

вот еще один вариант использования функции генератора, которая работает для целых чисел:

def ncomma(num):
    def _helper(num):
        # assert isinstance(numstr, basestring)
        numstr = '%d' % num
        for ii, digit in enumerate(reversed(numstr)):
            if ii and ii % 3 == 0 and digit.isdigit():
                yield ','
            yield digit

    return ''.join(reversed([n for n in _helper(num)]))

и вот тест:

>>> for i in (0, 99, 999, 9999, 999999, 1000000, -1, -111, -1111, -111111, -1000000):
...     print i, ncomma(i)
... 
0 0
99 99
999 999
9999 9,999
999999 999,999
1000000 1,000,000
-1 -1
-111 -111
-1111 -1,111
-111111 -111,111
-1000000 -1,000,000

Я предпочитаю решение на основе локали для реальных проектов, но я думаю, что подход с использованием назначения среза должен быть упомянут здесь:

def format_money(f, delimiter=',', frac_digits=2):

    negative_fix = int(f < 0)

    s = '%.*f' % (frac_digits, f)
    if len(s) < 5 + frac_digits + negative_fix:
        return s

    l = list(s)
    l_fix = l[negative_fix:]
    p = len(l_fix) - frac_digits - 5
    l_fix[p::-3] = [i + delimiter for i in l_fix[p::-3]]

    return ''.join(l[:negative_fix] + l_fix)

Суть с докторантами здесь -https://gist.github.com/ei-grad/b290dc761ae253af69438bbb94d82683

для поплавков:

float(filter(lambda x: x!=',', '1,234.52'))
# returns 1234.52

для ints:

int(filter(lambda x: x!=',', '1,234'))
# returns 1234

Если вы не хотите зависеть от каких-либо внешних библиотек:

 s = str(1234567)
 print ','.join([s[::-1][k:k+3][::-1] for k in xrange(len(s)-1, -1, -3)])

это работает только для целых неотрицательных чисел.

Comments

    Ничего не найдено.