Форматування валюти в Python


156

Я хочу відформатувати таке число, як 188518982,18 - 188,518,982.18 за допомогою Python.

Як я можу це зробити?


Ви зробили чудову думку в коментарі нижче, @RailsSon: ви хочете надрукувати £ s для відображення конкретної валюти, але використовувати цей показ, використовуючи японський вираз для фінансових цифр. Мені здається дивним, що ваш запит не був реалізований мовою шляхом роз'єднання використання localeмодулем вартості валюти та властивостей відображення цієї валюти.
Droogans

Відповіді:


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: Це питання про хитрість. Японський звіт означає японські правила з комою та десятковими знаками, але символ валюти GB Фунт - не тривіально підтримується мовою Locale. Ви повинні створити індивідуальне визначення локалі.
S.Lott

якщо число надаючого від'ємне, повертає значення між "()", чому?
panchicore

6
Це все ще не спрацювало для мене, але я змінив його, locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')і він працював ідеально!
Furbeenator

2
@panchicore позначення негативних чисел, що позначаються в дужках, є звичною практикою у світі бухгалтерського обліку. Спробуйте це в oocalc або excel і відформатуйте номери до типу обліку.
Droogans

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
@Josh, "з місцевої валюти імпорту".
Ендрю Х

5
@mrooney: Ви можете просто зробити: "$ {: 0, .2f}". формат (184467616.1), і тепер у вас є символ
триєдиність

@triunenature, що може призвести до $ 123,456.78інколи. Редагувати: розмітка займає додаткові пробіли,
роби

48

Не зовсім впевнений, чому це не згадується більше в Інтернеті (або в цій темі), але пакет Babel (і утиліти Django) від хлопців Edgewall є приголомшливим для форматування валюти (і безлічі інших завдань i18n). Це добре, тому що він не страждає від необхідності робити все в усьому світі, як основний модуль локалізації Python.

Приклад, який наводив ОП, просто:

>>> import babel.numbers
>>> import decimal
>>> babel.numbers.format_currency( decimal.Decimal( "188518982.18" ), "GBP" )
£188,518,982.18

2
Дуже пізня зауваження: тестуючи це, воно не здається інтелектуально форматованою валютою, оскільки воно просто наклеює відповідний символ перед сумою (відформатованою у тому, що ви вказали місце, яке ви встановили, що є розумним), незалежно від того, чи справді ця валюта використовує свій символ як префікс.
kungphu

@kungphu Що ти маєш на увазі? Дивіться babel.pocoo.org/en/latest/api/…
Джуліан

1
@Julian Схоже, localeаргумент format_currencyможна використовувати для вирішення цього питання, але або цього не було в документі чотири роки тому (коли я писав цей коментар), або я просто перевірив код цієї відповіді як - це не перевіряючи документа.
kungphu

1
@kungphu Gotcha. Я, мабуть, не звертав уваги на вік цієї посади вчора. Зміна документації / функції здається дуже ймовірною. Ура!
Джуліан

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

І для оригінального плакату, очевидно, тільки перемикач $для£


мій формат потребував певного налаштування, але це нормально, тому що я зміг це зробити за допомогою цього рішення.
DonkeyKong

9
Класна ідея! З Python 3.6 та f-струнами це виглядає ще красивіше:print(f'Value is: ${value:,.2f}'.replace('$-', '-$'))
Тімо


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

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

1
Модуль локалізації python не працював для мене (незалежно від того, якою я локаллю його встановив, він скаржився), але вимагає використання babel і використання цієї функції. Варто ознайомитись з документами API, оскільки там більше параметрів і корисніших функцій (наприклад, для валют:) format_currency.
Даніель В.

3

О, це цікавий звір.

Я витратив чималий час на отримання права, є три основні проблеми, які відрізняються від локальної до локальної: - символ валюти та напрямок - роздільник тисяч - десяткова крапка

Я написав власну досить масштабну реалізацію цього, що є частиною рамки ківі пітона, ознайомтеся з джерелом LGPL: ed тут:

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

Код трохи специфічний для Linux / Glibc, але він не повинен бути занадто складним для прийняття до Windows або інших Unix.

Після встановлення ви можете зробити наступне:

>>> 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

# надрукувати змінну "Усього:" у такому форматі "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

Лямбда для обчислення її всередині функції за допомогою відповіді @ 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 Byström

@jonas Можливо, це роблять більшість країн, але ОП це було раніше суми, отже, я отримав його до суми у своїй відповіді :)
му mu

0

Простий код пітона!

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)

1
Ваш код повертає рядки подобається "$2,129.1468284147656", "$10,948.3742933", "$1,0908". Затягує струну.
Євген Гр. Філіппов

Так, я не помітив. Ви також дали анс.
Ванджіт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.