Форматирование валюты в Python

156

Я хочу отформатировать число, например, 188518982,18 в £ 188,518,982.18, используя Python.

Как я могу это сделать?

RailsSon
источник
Вы отметили превосходное замечание в комментарии ниже, @RailsSon: вы хотите напечатать £ s, чтобы отобразить определенную валюту, но использовать это отображение, используя японское выражение для финансовых чисел. Мне кажется странным, что ваш запрос не был реализован на языке из-за разделения использования localeмодулем значения валюты и свойств отображения этой валюты.
Дрооганс

Ответы:

212

Смотрите модуль локали .

Это делает форматирование валюты (и даты).

>>> import locale
>>> locale.setlocale( locale.LC_ALL, '' )
'English_United States.1252'
>>> locale.currency( 188518982.18 )
'$188518982.18'
>>> locale.currency( 188518982.18, grouping=True )
'$188,518,982.18'
С. Лотт
источник
15
Как правильно отформатировать не родную валюту, скажем, я показываю стоимость в фунтах стерлингов для отчета на японском языке?
SingleNegationElimination
2
@TokenMacGuy: это вопрос с подвохом. Японский отчет означает японские правила запятой и десятичного разряда, но символ валюты фунта стерлингов - нетривиально поддерживаемый Locale. Вы должны создать настроенное определение локали.
S.Lott
если дающий номер отрицательный, возвращает значение между "()" почему?
Panchicore
6
Это все еще не работало для меня, но я изменил это, locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')и это работало отлично!
Furbeenator
2
@panchicore обозначение для отрицательных чисел, обозначаемое в скобках, является обычной практикой в ​​мире бухгалтерского учета. Попробуйте это в oocalc или excel, и отформатируйте числа в соответствии с типом учета.
Дрооганс
94

Новое в 2.7

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

http://docs.python.org/dev/whatsnew/2.7.html#pep-0378

Нейт С
источник
6
Это аккуратно, но на самом деле не отвечает на вопрос, так как запрошенное решение будет включать символ валюты, и вы также жестко задаете количество цифр после десятичной дроби, которая зависит от конкретной локали. Есть много других причин, чтобы использовать принятый языковой ответ, если вы не хотите просто ставить запятую.
mrooney
6
@mrooney Существует также много причин, по которым не следует использовать принятый языковой ответ, например, не импортировать весь модуль.
Джош
1
@ Джош, "из валюты импорта локали".
Эндрю Х
5
@mrooney: Вы можете просто сделать: '$ {: 0, .2f}'. format (184467616.1), и теперь у вас есть символ
триненатура
@triunenature, что $ 123,456.78иногда приводит к тому, что. Изменить: уценка убирает лишние пробелы, притвориться, что есть больше между $ и числами
CyberJacob
48

Не совсем понятно, почему он не упоминается более онлайн (или в этой ветке), но пакет Babel (и утилиты Django) от ребят из Edgewall хорош для форматирования валюты (и множества других задач i18n). Это приятно, потому что он не страдает от необходимости делать все глобально, как основной языковой модуль Python.

Пример, приведенный OP, будет просто:

>>> import babel.numbers
>>> import decimal
>>> babel.numbers.format_currency( decimal.Decimal( "188518982.18" ), "GBP" )
£188,518,982.18
glenc
источник
2
Очень позднее примечание: проверяя это, он, по-видимому, не разумно форматирует валюту, поскольку он просто вставляет соответствующий символ перед суммой (отформатирован в том, что, кажется, является языковым стандартом, который вы установили, что является разумным), независимо от того, действительно ли эта валюта использует его символ в качестве префикса.
кунгфу
@kungphu Что ты имеешь в виду? См. Babel.pocoo.org/en/latest/api/…
Джулиан,
1
@Julian Похоже, localeаргумент, который format_currencyможно использовать для решения этой проблемы, но либо этого не было в документе четыре года назад (когда я писал этот комментарий), либо я просто протестировал код этого ответа как есть, не проверяя документ.
Кунгфу
1
@kungphu Gotcha. Должно быть, я не обращал внимания на возраст этого поста вчера. Изменение документации / функций представляется весьма вероятным. Ура!
Julian
32

Это древний пост, но я только что реализовал следующее решение, которое:

  • Не требует внешних модулей
  • Не требует создания новой функции
  • Может быть сделано в линии
  • Обрабатывает несколько переменных
  • Обрабатывает отрицательные суммы в долларах

Код:

num1 = 4153.53
num2 = -23159.398598

print 'This: ${:0,.0f} and this: ${:0,.2f}'.format(num1, num2).replace('$-','-$')

Вывод:

This: $4,154 and this: -$23,159.40

И для оригинального плаката, очевидно, просто переключитесь $на£

elPastor
источник
Мой формат нуждается в некоторой настройке, но это нормально, потому что я смог сделать это с этим решением.
DonkeyKong
10
Классная идея! С Python 3.6 и f-strings это выглядит еще красивее:print(f'Value is: ${value:,.2f}'.replace('$-', '-$'))
Тимо Салоранта
16

Мои настройки локали казались неполными, поэтому я слишком посмотрел за пределы этого ответа SO и обнаружил:

http://docs.python.org/library/decimal.html#recipes

ОС-независимый

Просто хотел поделиться здесь.

user37986
источник
Но где мы называем def moneyfmt(value, places=2, curr='', sep=',', dp='.', pos='', neg='-', trailneg='')?
Roel
9

Если вы используете OSX и еще не установили настройки модуля локали, этот первый ответ не будет работать, вы получите следующую ошибку:

Traceback (most recent call last):File "<stdin>", line 1, in <module> File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/locale.py", line 221, in currency
raise ValueError("Currency formatting is not possible using "ValueError: Currency formatting is not possible using the 'C' locale.

Чтобы исправить это, вы должны будете использовать следующее:

locale.setlocale(locale.LC_ALL, 'en_US')
Simoes
источник
2
locale.setlocale (locale.LC_ALL, 'en_US.UTF-8') делает для меня
alexblum
9

"{:0,.2f}".format(float(your_numeric_value))в Python 3 делает свою работу; он выдает что-то вроде одной из следующих строк:

10,938.29
10,899.00
10,898.99
2,328.99
Евгений Гр. Филиппова
источник
6

На вашем месте я бы использовал BABEL: http://babel.pocoo.org/en/latest/index.html

from babel.numbers import format_decimal


format_decimal(188518982.18, locale='en_US')
Carlos
источник
1
Модуль языка Python не работал для меня (какой бы язык я ни устанавливал, он жаловался), но требовать babel и использовать эту функцию - это хорошо. Стоит взглянуть в документацию по API, так как есть больше параметров и более полезных функций (например, для валют:) format_currency.
Даниэль В.
3

О, это интересный зверь.

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

Я написал свою довольно обширную реализацию этого, которая является частью платформы Python kiwi, посмотрите источник LGPL: ed здесь:

http://svn.async.com.br/cgi-bin/viewvc.cgi/kiwi/trunk/kiwi/currency.py?view=markup

Код немного специфичен для Linux / Glibc, но не должен быть слишком сложным для адаптации к windows или другим unixes.

После того, как вы установили это, вы можете сделать следующее:

>>> from kiwi.datatypes import currency
>>> v = currency('10.5').format()

Который затем даст вам:

'$10.50'

или

'10,50 kr'

В зависимости от текущей выбранной локали.

Главное, что этот пост имеет над другим, - то, что он будет работать со старыми версиями python. locale.currency был представлен в python 2.5.

Йохан Далин
источник
Есть ли у него преимущества перед locale.currency ()?
Али Афшар
@AliAfshar: одним из преимуществ было бы 10,50 krвместо kr 10,50.
user2394284
2

# печать переменной 'Total:' в формате, который выглядит следующим образом '9,348.237'

print ('Total:',   '{:7,.3f}'.format(zum1))

где '{: 7, .3f}' - количество пробелов для форматирования числа в этом случае - миллион с 3 десятичными точками. Затем вы добавляете '.format (zum1). Zum1 - это переменная, которая имеет большое число для суммы всех чисел в моей конкретной программе. Переменная может быть любой, которую вы решите использовать.

мари
источник
1

Вдохновленный кодом выше: D

def money_format(value):
value = str(value).split('.')
money = ''
count = 1

for digit in value[0][::-1]:
    if count != 3:
        money += digit
        count += 1
    else:
        money += f'{digit},'
        count = 1

if len(value) == 1:
    money = ('$' + money[::-1]).replace('$-','-$')
else:
    money = ('$' + money[::-1] + '.' + value[1]).replace('$-','-$')

return money
Элмер Гонсалес
источник
0

Я пришел посмотреть на то же самое и обнаружил, что Python-Money еще не использовал его, но, возможно, сочетание двух было бы хорошо

Джеймс Брукс
источник
0

Лямбда для вычисления внутри функции с помощью ответа @ Nate

converter = lambda amount, currency: "%s%s%s" %(
    "-" if amount < 0 else "", 
    currency, 
    ('{:%d,.2f}'%(len(str(amount))+3)).format(abs(amount)).lstrip())

а потом,

>>> converter(123132132.13, "$")
'$123,132,132.13'

>>> converter(-123132132.13, "$")
'-$123,132,132.13'
му 無
источник
Большинство стран используют символ валюты после суммы, а не наоборот.
Йонас Быстрем
@jonas Может быть, это то, что делают большинство стран, но у ОП это было до суммы, поэтому я получил ее до суммы в моем ответе :)
mu 無
0

Простой код на Python!

def format_us_currency(value):
    value=str(value)
    if value.count(',')==0:
        b,n,v='',1,value
        value=value[:value.rfind('.')]
        for i in value[::-1]:
            b=','+i+b if n==3 else i+b
            n=1 if n==3 else n+1
        b=b[1:] if b[0]==',' else b
        value=b+v[v.rfind('.'):]
    return '$'+(value.rstrip('0').rstrip('.') if '.' in value else value)
Vanjith
источник
1
Ваш код возвращает строки нравится "$2,129.1468284147656", "$10,948.3742933", "$1,0908". Искажает строку.
Евгений Гр. Филиппов
Да, я не заметил. Вы дали ответ тоже.
Ванджит