2010-10-11 4 views

ответ

87

Нет один до сих пор упоминается новый ',' вариант, который был добавлен в версии 2.7 к Спецификация формата Mini-Language - не видят PEP 378: Format Specifier for Thousands Separator в What's New in Python 2.7 document. Это легко использовать, потому что вам не нужно возиться с locale (но из-за этого он ограничен для интернационализации, см. original PEP 378). Он работает с поплавками, ints и десятичными знаками - и всеми другими функциями форматирования, предусмотренными в спецификации на мини-языке.

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

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

Примечание: Хотя эта новая функция, безусловно, удобно, это на самом деле не все гораздо сложнее использовать 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(). Однако спецификатор 'd'имеет значение, если вы используете вместо него функции locale.format() или locale.format_string().

+3

-1 К сожалению, это ** нарушено **; он увековечивает наследие языкового модуля - ** он не работает должным образом с unicode **. Попробуйте 'format (1234, u" n ")' в локали (например, на французском, русском), где разделитель тысяч - это NO-BREAK SPACE. Вы получаете любимое исключение новичков: 'UnicodeDecodeError: 'ascii' кодек не может декодировать байт 0xa0 ...' –

+1

@John Machin: для записи большинство изменений было сделано для этого ответа, прежде чем я добавил примечание об использовании 'locale' - и для всеобщего просветления, только что * является * правильным в настоящее время, почему для операции в локальном стиле, который будет обрабатывать Unicode? Благодарю. – martineau

+0

(1) Когда были сделаны upvotes, какая значимость? (2) Нет просветления, поддерживаемого Python-2.X, просто kludge: 'format (1234," n "). Decode (locale.getpreferredencoding())' :-( –

13

locale.format()

Не забудьте установить локаль соответствующим первым.

+0

И не забудьте указать значение «True» для необязательного аргумента _grouping_, например, в 'locale.format (u '% d', 1234, True)'. По-видимому, 'locale' не совсем неуместен в обработке Unicode (как замечают комментарии @John Machin в другом ответе). – martineau

10

Лишенный из 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 

Есть и другие решения here.

+0

+1 несмотря на docstring, похоже, что он обрабатывает как плавающие точки, так и целые числа. Использование имен переменных «доллары» и «центы», помимо того, что они слишком чрезмерно ориентированы на приложения, похоже, поддерживают эту гипотезу. Очень портативная версия Python, как представлено, вернется к версии 2.3, и если итератор 'enumerate()' был заменен чем-то эквивалентным, все возвращается к версии 2.0. – martineau

+1

Для Python 2.4+ 'str (dollars) [:: - 1]' может быть заменен на более читаемый 'reverse (str (доллары))'. – martineau

+0

@martineau хороший обзор, я использую эту функцию в Google App Engine, где Python ограничен версией 2.5 из коробки. – systempuntoout

4

Используйте целое число 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) 
Смежные вопросы