# How do I convert a currency string to a floating point number in Python?

## All we need is an easy explanation of the problem, so here it is.

I have some strings representing numbers with specific currency format, for example:

``````money="\$6,150,593.22"
``````

I want to convert this string into the number

``````6150593.22
``````

What is the best way to achieve this?

## How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

### Method 1

Try this:

``````from re import sub
from decimal import Decimal

money = '\$6,150,593.22'
value = Decimal(sub(r'[^\d.]', '', money))
``````

This has some advantages since it uses `Decimal` instead of `float` (which is better for representing currency) and it also avoids any locale issues by not hard-coding a specific currency symbol.

### Method 2

If your locale is set properly you can use `locale.atof`, but you will still need to strip off the ‘\$’ manually:

``````>>> import locale
>>> locale.setlocale(locale.LC_ALL, 'en_US.UTF8')
'en_US.UTF8'
>>> money = "\$6,150,593.22"
>>> locale.atof(money.strip("\$"))
6150593.2199999997
``````

### Method 3

For a solution without hardcoding the currency position or symbol:

``````raw_price = "17,30 €"
import locale
locale.setlocale(locale.LC_ALL, 'fr_FR.UTF8')
conv = locale.localeconv()
raw_numbers = raw_price.strip(conv['currency_symbol'])
amount = locale.atof(raw_numbers)
``````

### Method 4

I found the `babel` package very helpful to work around

It makes it easy to parse a number in a localized rendition:

``````>>> babel.numbers.parse_decimal('1,024.64', locale='en')
Decimal('1024.64')
>>> babel.numbers.parse_decimal('1.024,64', locale='de')
Decimal('1024.64')
>>>
``````

You can use `babel.numbers.get_currency_symbol('USD')` to strip pre/suffixes without hardcoding them.

Hth,
dtk

### Method 5

Expanding to include negative numbers in parentheses:

``````In [1]: import locale, string

In [2]: from decimal import Decimal

In [3]: n = ['\$1,234.56','-\$1,234.56','(\$1,234.56)', '\$ -1,234.56']

In [4]: tbl = string.maketrans('(','-')

In [5]: %timeit -n10000 [locale.atof( x.translate(tbl, '\$)')) for x in n]
10000 loops, best of 3: 31.9 æs per loop

In [6]: %timeit -n10000 [Decimal( x.translate(tbl, '\$,)')) for x in n]
10000 loops, best of 3: 21 æs per loop

In [7]: %timeit -n10000 [float( x.replace('(','-').translate(None, '\$,)')) for x in n]
10000 loops, best of 3: 3.49 æs per loop

In [8]: %timeit -n10000 [float( x.translate(tbl, '\$,)')) for x in n]
10000 loops, best of 3: 2.19 æs per loop
``````

Note that commas must be stripped from float()/Decimal(). Either replace() or translate() w/ a translation table can be used to convert the opening ( to -, translate is slightly faster. float() is fastest by 10-15x, but lacks precision and could present locale issues. Decimal() has precision and is 50% faster than locale.atof(), but also has locale issues. locale.atof() is the slowest, but most general.

Edit: new `str.translate` API (characters mapped to `None` moved from `str.translate` function to the translation table)

``````In [1]: import locale, string
from decimal import Decimal

locale.setlocale(locale.LC_ALL, '')

n = ['\$1,234.56','-\$1,234.56','(\$1,234.56)', '\$ -1,234.56']

In [2]: tbl = str.maketrans('(', '-', '\$)')
%timeit -n10000 [locale.atof( x.translate(tbl)) for x in n]
18 µs ± 296 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [3]: tbl2 = str.maketrans('(', '-', '\$,)')
%timeit -n10000 [Decimal( x.translate(tbl2)) for x in n]
3.77 µs ± 50.8 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [4]: %timeit -n10000 [float( x.translate(tbl2)) for x in n]
3.13 µs ± 66.3 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [5]: tbl3 = str.maketrans('', '', '\$,)')
%timeit -n10000 [float( x.replace('(','-').translate(tbl3)) for x in n]
3.51 µs ± 84.8 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
``````

### Method 6

I made this function a few years ago to solve the same problem.

``````def money(number):
number = number.strip('\$')
try:
[num,dec]=number.rsplit('.')
dec = int(dec)
aside = str(dec)
x = int('1'+'0'*len(aside))
price = float(dec)/x
num = num.replace(',','')
num = int(num)
price = num + price
except:
price = int(number)
return price
``````

### Method 7

this function has convert turkish price format to decimal number.

``````money = '1.234,75'
def make_decimal(string):
result = 0
if string:
[num, dec] = string.rsplit(',')
result += int(num.replace('.', ''))
result += (int(dec) / 100)
return result
print(make_decimal(money))
1234.75
``````

### Method 8

Simplest way I found, without hard-coding on messing with currency detection, also uses the `Decimal` type which avoids issues with the `float` type:

``````>>> from decimal import Decimal
>>> money="\$6,150,593.22"
>>> amount = Decimal("".join(d for d in money if d.isdigit() or d == '.'))
>>> amount
Decimal('6150593.22')

``````

### Method 9

I’ll provide my solution, hoping it would help someone who face problems with not just `,` but also `.`.

``````def process_currency_adaptive(currency_string: str, decimal_sep_char: str) -> float:
"""
Converts the currency string to common float format:
Format:
######.###
Example:
6150593.22
"""
# Get rid of currency symbol
currency_symbols = ["\$", "€", "£", "₺"]

# Replace any occurrence of currency symbol with empty string
for symbol in currency_symbols:
currency_string = currency_string.replace(symbol, "")

if decimal_sep_char == ",":
triple_sep_char = "."
elif decimal_sep_char == ".":
triple_sep_char = ","
else:
raise ValueError("Invalid decimal separator character: {}".format(decimal_sep_char))

# Get rid of the triple separator
currency_string = currency_string.replace(triple_sep_char, "")

# There should be only one decimal_sep_char.
if currency_string.count(decimal_sep_char) != 1:
print("Error: Invalid currency format with value: {}".format(currency_string))
raise ValueError

return float(currency_string.replace(decimal_sep_char, "."))

# test process_currency