Formatowanie walut w Pythonie


156

Chcę sformatować liczbę taką jak 188518982,18 do 188 518 982,18 GBP za pomocą Pythona.

W jaki sposób mogę to zrobić?


W poniższym komentarzu @RailsSon wskazałeś na doskonały punkt: chcesz wydrukować funty, aby wyświetlić określoną walutę, ale zastosuj ten sposób wyświetlania, używając japońskiego wyrażenia dla liczb finansowych. Wydaje mi się dziwne, że twoje żądanie nie zostało zaimplementowane w języku poprzez oddzielenie localeużycia wartości waluty przez moduł i właściwości wyświetlania tej waluty.
Droogans

Odpowiedzi:


212

Zobacz moduł locale .

Dotyczy to formatowania waluty (i daty).

>>> 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
Jak poprawnie sformatować obcą walutę, powiedzmy, że pokazuję koszt w funtach brytyjskich dla raportu w języku japońskim?
SingleNegationElimination,

2
@TokenMacGuy: To podstępne pytanie. Raport japoński oznacza japońskie zasady dotyczące przecinków i miejsc dziesiętnych, ale symbol waluty funta GB - nie jest trywialnie obsługiwany przez Locale. Musisz utworzyć niestandardową definicję ustawień regionalnych.
S.Lott,

jeśli liczba dawcy jest ujemna, zwraca wartość między „()”, dlaczego?
panchicore

6
To nadal nie działało dla mnie, ale zmieniłem to locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')i działało idealnie!
Furbeenator

2
@panchicore notacja liczb ujemnych zapisywana w nawiasach jest powszechną praktyką w świecie rachunkowości. Wypróbuj w oocalc lub excel i sformatuj liczby zgodnie z typem rozliczania.
Droogans

94

Nowość w wersji 2.7.0

>>> '{: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
To fajne, ale tak naprawdę nie odpowiada na pytanie, ponieważ żądane rozwiązanie zawierałoby symbol waluty, a także wpisujesz na stałe liczbę cyfr po przecinku, co jest specyficzne dla lokalizacji. Istnieje wiele innych powodów, dla których warto użyć akceptowanej odpowiedzi dotyczącej języka, jeśli nie chcesz umieszczać tylko przecinków.
mrooney

6
@mrooney Istnieje również wiele powodów, dla których nie należy używać akceptowanej odpowiedzi dotyczącej ustawień regionalnych, na przykład nie importowanie całego modułu.
Josh

1
@Josh, „z lokalnej waluty importu”.
Andrew H

5
@mrooney: Możesz po prostu zrobić: format „$ {: 0, .2f}” (184467616.1) i masz teraz symbol
triunenature

@triunenature, co $ 123,456.78czasami skutkuje . Edycja:
Markdown usuwa

48

Nie do końca jestem pewien, dlaczego nie wspomniano o tym więcej w Internecie (lub w tym wątku), ale pakiet Babel (i narzędzia Django) od facetów z Edgewall jest świetny do formatowania walut (i wielu innych zadań i18n). To fajne, ponieważ nie cierpi z powodu konieczności robienia wszystkiego globalnie, jak rdzeń modułu lokalnego dla Pythona.

Przykład podany przez PO wyglądałby po prostu:

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

2
Bardzo późna uwaga: testując to, nie wydaje się, aby inteligentnie formatował walutę, ponieważ po prostu umieszcza odpowiedni symbol przed kwotą (sformatowaną w ustawionym przez Ciebie ustawieniu regionalnym, co jest rozsądne), niezależnie od tego, czy ta waluta faktycznie używa swojego symbolu jako przedrostka.
kungphu

@kungphu Co masz na myśli? Zobacz babel.pocoo.org/en/latest/api/…
Julian

1
@Julian Wygląda na to, że locale argument do format_currencymoże zostać użyty do rozwiązania tego problemu, ale albo tego nie było w dokumencie cztery lata temu (kiedy pisałem ten komentarz), albo właśnie przetestowałem kod tej odpowiedzi bez sprawdzania dokumentu.
kungphu

1
@kungphu Gotcha. Wczoraj chyba nie zwracałem uwagi na wiek tego wpisu. Zmiana dokumentacji / funkcji wydaje się bardzo prawdopodobna. Twoje zdrowie!
Julian

32

To jest starożytny post, ale właśnie wdrożyłem następujące rozwiązanie, które:

  • Nie wymaga zewnętrznych modułów
  • Nie wymaga tworzenia nowej funkcji
  • Można to zrobić w linii
  • Obsługuje wiele zmiennych
  • Obsługuje ujemne kwoty w dolarach

Kod:

num1 = 4153.53
num2 = -23159.398598

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

Wynik:

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

A jeśli chodzi o oryginalny plakat, po prostu przełącz się $na£


mój format wymagał dostosowania, ale to jest w porządku, ponieważ mogłem to zrobić za pomocą tego rozwiązania.
DonkeyKong

9
Fajny pomysł! Z Pythonem 3.6 i f-stringami wygląda jeszcze piękniej:print(f'Value is: ${value:,.2f}'.replace('$-', '-$'))
Timo Saloranta

16

Moje ustawienia regionalne wydawały się niekompletne, więc również spojrzałem poza tę TAK odpowiedź i znalazłem:

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

Niezależny od systemu operacyjnego

Chciałem się tu tylko podzielić.


Ale gdzie nazywamy to def moneyfmt(value, places=2, curr='', sep=',', dp='.', pos='', neg='-', trailneg='')?
Roel

9

Jeśli używasz OSX i nie ustawiłeś jeszcze swojego modułu ustawień regionalnych, to pierwsza odpowiedź nie zadziała, pojawi się następujący błąd:

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.

Aby temu zaradzić, będziesz musiał wykonać następujące czynności:

locale.setlocale(locale.LC_ALL, 'en_US')

2
locale.setlocale (locale.LC_ALL, 'en_US.UTF-8') robi dla mnie
alexblum

9

"{:0,.2f}".format(float(your_numeric_value))w Pythonie 3 spełnia swoje zadanie; wyświetla coś podobnego do jednej z następujących linii:

10,938.29
10,899.00
10,898.99
2,328.99

6

Na twoim miejscu użyłbym BABEL: http://babel.pocoo.org/en/latest/index.html

from babel.numbers import format_decimal


format_decimal(188518982.18, locale='en_US')

1
Moduł locale Pythona nie działał dla mnie (niezależnie od ustawień lokalnych, narzekał), ale wymaganie Babel i używanie tej funkcji jest przyjemne. Warto zajrzeć do dokumentacji API, ponieważ jest więcej parametrów i bardziej przydatnych funkcji (jak dla walut:) format_currency.
Daniel W.

3

Och, to interesująca bestia.

Spędziłem dużo czasu, aby to naprawić, istnieją trzy główne kwestie, które różnią się w zależności od lokalizacji: - symbol waluty i kierunek - separator tysięcy - przecinek dziesiętny

Napisałem własną, dość obszerną implementację tego, która jest częścią frameworka kiwi Python, sprawdź źródło LGPL: ed tutaj:

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

Kod jest nieco specyficzny dla Linuksa / Glibc, ale nie powinien być zbyt trudny do zaadaptowania do Windows lub innych uniksów.

Po zainstalowaniu możesz wykonać następujące czynności:

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

Który następnie da ci:

'$10.50'

lub

'10,50 kr'

W zależności od aktualnie wybranej lokalizacji.

Głównym punktem, który ten post ma nad innymi, jest to, że będzie działać ze starszymi wersjami Pythona. locale.currency zostało wprowadzone w Pythonie 2.5.


Czy ma przewagę nad locale.currency ()?
Ali Afshar

@AliAfshar: 10,50 krZamiast tego byłaby jedna korzyść kr 10,50.
user2394284

2

#printing zmiennej „Total:” w formacie, który wygląda następująco: „9,348,237”

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

gdzie „{: 7, .3f}” to liczba spacji do sformatowania liczby w tym przypadku to milion z 3 miejscami po przecinku. Następnie dodajesz '.format (zum1). Zum1 to zmienna, która ma dużą liczbę będącą sumą wszystkich liczb w moim konkretnym programie. Zmienna może być wszystkim, czego zdecydujesz się użyć.


1

Zainspirowany powyższym kodem: 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

Lambda do obliczania jej wewnątrz funkcji, z pomocą odpowiedzi @ Nate'a

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

i wtedy,

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

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

Większość krajów używa symbolu waluty po kwocie, a nie odwrotnie.
Jonas Byström

@jonas Może tak robi większość krajów, ale OP miał to przed kwotą, stąd też mam to przed kwotą w mojej odpowiedzi :)
mu 無

0

Prosty kod w Pythonie!

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
Przywracany kod ciągi podoba "$2,129.1468284147656", "$10,948.3742933", "$1,0908". Niszczy sznurek.
Eugene Gr. Philippov

Tak, nie zauważyłem. Ty też dałeś odpowiedzi.
Vanjith
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.