RailsSon
RailsSon

Reputation: 20637

Currency formatting in Python

I am looking to format a number like 188518982.18 to £188,518,982.18 using Python.

How can I do this?

Upvotes: 219

Views: 309327

Answers (17)

omarfsosa
omarfsosa

Reputation: 21

Python has detailed help section under help("FORMATTING") on how to format strings. Some of these features are only available in recent versions of python though. This is how I'd do it:

def _formatted_len(s: float, decimals: int = 2, sign: str = "-"):
    """
    Figure out the length of the string representation of s
    that includes commas, decimal point, decimals, and sign (if any)
    """
    formatted_s = f"{s:{sign},.{decimals}f}"
    return len(formatted_s)

def currency(x: float, symbol: str = "$", decimals: int = 2, sign: str  = "-"):
    """
    Format the number `x` as a currency.

    Args:
        x: The numerical value of the currency
        symbol: The currency symbol (e.g. $, £, etc.)
        decimals: How many digits to include after the decimal point
        sign: How to sign the value, options are:
            '+': uses a sign for both positive and negative values
            '-': uses a sign for negative values only
            ' ': sign negative numbers and leave a blank space if positive

    Returns:
        A string representing the currency
    """
    assert len(symbol) == 1
    assert sign in ["-", "+", " "]
    length = _formatted_len(x, decimals, sign)
    return f"{x:{symbol}={sign}{length + 1},.{decimals}f}"


print(currency(1234.567, sign=" "))
print(currency(-3000.1234, decimals=3, sign="+"))
print(currency(1e4, symbol="£", decimals=0, sign="-"))  

Output:

 $1,234.57
-$3,000.123
£10,000

Upvotes: 0

Renato Teixeira Lima
Renato Teixeira Lima

Reputation: 19

Simple way:

Install bable package: pip install babel

Create currency.py file and...

from babel.numbers import format_currency

def format_currency_brl(value): return format_currency(value, 'BRL', locale='pt_BR')

Works like a charm...

Upvotes: 0

Tim D
Tim D

Reputation: 1743

With only Python Standard Library imports, this is a compact way of defining a custom format:

>>> from functools import partial
>>> import locale
>>> locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')  # or whatever locale you want
>>> _c = partial(locale.currency, grouping=True)
>>> my_amount = 188518982.18
>>> print(f'{_c(my_amount)}')
$188,518,982.18

Upvotes: 0

neves
neves

Reputation: 39173

There are already a dozen solutions here, but I believe the one below is the best, because:

  • it is simple
  • obeys the OS locale
  • no external lib is needed
  • you can make it concise

My solution is to use locale.currency() method:

import locale
# this sets locale to the current Operating System value
locale.setlocale(locale.LC_ALL, '') 
print(locale.currency(1346896.67444, grouping=True, symbol=True)

will output in my Windows 10 configured to Brazilian Portuguese:

R$ 1.346.896,67

It is somewhat verbose, so if you will use it a lot, maybe it is better to predefine some parameters and have a shorter name and use it inside a f-string:

fmt = lambda x: locale.currency(x, grouping=True, symbol=True)
print(f"Value: {fmt(1346896.67444)}"

You can pass a locale value for the setlocale method, but its value is OS dependent, so beware. If you are in a *nix server, you also need to check if your desired locale is correctly installed in the OS.

You also can turn off the symbol passing symbol=False.

Upvotes: 11

S.Lott
S.Lott

Reputation: 391846

See the locale module.

This does currency (and date) formatting.

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

Upvotes: 287

Elmer Gonzalez
Elmer Gonzalez

Reputation: 21

Inspired by the code above :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

Upvotes: 2

Eugene Gr. Philippov
Eugene Gr. Philippov

Reputation: 2092

"{:0,.2f}".format(float(your_numeric_value)) in Python 3 does the job; it gives out something like one of the following lines:

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

Upvotes: 28

Vanjith
Vanjith

Reputation: 540

Simple python code!

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)

Upvotes: 0

Carlos
Carlos

Reputation: 777

If I were you, I would use BABEL: http://babel.pocoo.org/en/latest/index.html

from babel.numbers import format_decimal


format_decimal(188518982.18, locale='en_US')

Upvotes: 11

elPastor
elPastor

Reputation: 8956

This is an ancient post, but I just implemented the following solution which:

  • Doesn't require external modules
  • Doesn't require creating a new function
  • Can be done in-line
  • Handles multiple variables
  • Handles negative dollar amounts

Code:

num1 = 4153.53
num2 = -23159.398598

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

Output:

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

And for the original poster, obviously, just switch $ for £

Upvotes: 55

Marie
Marie

Reputation: 31

#printing the variable 'Total:' in a format that looks like this '9,348.237'

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

where the '{:7,.3f}' es the number of spaces for formatting the number in this case is a million with 3 decimal points. Then you add the '.format(zum1). The zum1 is tha variable that has the big number for the sum of all number in my particular program. Variable can be anything that you decide to use.

Upvotes: 3

glenc
glenc

Reputation: 3172

Not quite sure why it's not mentioned more online (or on this thread), but the Babel package (and Django utilities) from the Edgewall guys is awesome for currency formatting (and lots of other i18n tasks). It's nice because it doesn't suffer from the need to do everything globally like the core Python locale module.

The example the OP gave would simply be:

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

Upvotes: 58

Anshul Goyal
Anshul Goyal

Reputation: 76877

A lambda for calculating it inside a function, with help from @Nate's answer

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

and then,

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

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

Upvotes: 0

simoes
simoes

Reputation: 5036

If you are using OSX and have yet to set your locale module setting this first answer will not work you will receive the following error:

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.

To remedy this you will have to do use the following:

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

Upvotes: 12

nate c
nate c

Reputation: 9005

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

Upvotes: 115

user37986
user37986

Reputation: 1127

My locale settings seemed incomplete, so I had too look beyond this SO answer and found:

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

OS-independent

Just wanted to share here.

Upvotes: 18

Johan Dahlin
Johan Dahlin

Reputation: 26496

Oh, that's an interesting beast.

I've spent considerable time of getting that right, there are three main issues that differs from locale to locale: - currency symbol and direction - thousand separator - decimal point

I've written my own rather extensive implementation of this which is part of the kiwi python framework, check out the LGPL:ed source here:

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

The code is slightly Linux/Glibc specific, but shouldn't be too difficult to adopt to windows or other unixes.

Once you have that installed you can do the following:

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

Which will then give you:

'$10.50'

or

'10,50 kr'

Depending on the currently selected locale.

The main point this post has over the other is that it will work with older versions of python. locale.currency was introduced in python 2.5.

Upvotes: 3

Related Questions