2

I need to convert a string currency string in Continental Europe format into a float number:

Input:

'6.150.593,22 €'

Realize that decimal point is comma, and thousands separators are period characters.

Output:

6150593.22

I'd read these questions, but they only works for US dollar currency and locale:

currency_euros='6.150.593,22 €'
float(currency_euros[:-2])
Traceback (most recent call last):
  File "<pyshell#28>", line 1, in <module>
    float(currency_euros[:-2])
ValueError: could not convert string to float: '6.150.593,22'

Updated: Following the @IrmendeJong answer:

>>> import locale
>>> locale.setlocale(locale.LC_NUMERIC, "es")
'es'
>>> print(locale.currency(6150593.22))
6150593,22 €
>>> money = '6.150.593,22 €'
>>> locale.atof(money)
Traceback (most recent call last):
  File "<pyshell#68>", line 1, in <module>
    locale.atof(money)
  File "C:\Python35\lib\locale.py", line 318, in atof
    return func(delocalize(string))
ValueError: could not convert string to float: '6150593.22 €'
>>> 

I'm ashtonished that locale.currency() works fine but its reciprocal method locale.atof() doesn't work.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
Trimax
  • 2,413
  • 7
  • 35
  • 59
  • Simply remove all dots and replace the comma with a dot. Strip off non float characters – Moses Koledoye Nov 21 '16 at 09:47
  • Check out the `locale` module. https://docs.python.org/3/library/locale.html – p-robot Nov 21 '16 at 09:49
  • Yes, I know how to eliminate the Eur(€) symbol for a string, but at this moment, the question is that locale.atof() doesn't support the currency symbol character. – Trimax Nov 21 '16 at 10:42
  • 1
    Do note that if you are using this in a financial application, the ``float`` datatype is actually not the best choice (because it loses precision). ``decimal.Decimal`` is better but it's a bit harder to parse then because you won't be able to use ``locale.atof``. I guess you'll have to convert the thousands separator and decimal comma yourself to something that ``decimal.Decimal("...")`` understands – Irmen de Jong Nov 21 '16 at 13:09

5 Answers5

10

Use locale.atof https://docs.python.org/3/library/locale.html#locale.atof

>>> import locale
>>> locale.setlocale(locale.LC_NUMERIC,"nl")
'nl'
>>> locale.atof("6.150.593,22")
6150593.22
Irmen de Jong
  • 2,739
  • 1
  • 14
  • 26
  • Thanks for showing me the `locale.atof()` method but it doesn't work with de Eur(€) symbol while the reciprocal method `locale.currency()` seems to support it. I've updated my question. – Trimax Nov 21 '16 at 10:40
  • ``atof`` is for parsing a number. Any currency symbol(s) are not part of the actual number. It depends on the situation and application how they are represented! For instance, in some systems I've encountered € in front, at the end, or ``EUR`` in front or at the end, separated by either one or more tabs and/or spaces. It's up to you I guess to strip off the currency symbol so you only pass the actual number string to ``atof``. – Irmen de Jong Nov 21 '16 at 12:59
3

A good way of doing it (1 line) :

NewValue = float(value[:-2].replace(".", "").replace(",","."))
Mohamed AL ANI
  • 2,012
  • 1
  • 12
  • 29
1
value = '6.150.593,22 €'
value = value.split()[0]              #Take out euro symbol
integer, decimal = value.split(',')   #Separate integer and decimals
integer = integer.replace('.','')     #Take out dots
final_value = int(integer) + (int(decimal) * (10**(-len(decimal))))
wildwilhelm
  • 4,809
  • 1
  • 19
  • 24
Jalo
  • 1,131
  • 1
  • 12
  • 28
1

A simple solution may be as follows:

>>> val = '6.150.593,22 €'
>>> res = val[:-2].split(',')
>>> float('.'.join([res[0].replace('.', ''), res[1]]))
6150593.22
ettanany
  • 19,038
  • 9
  • 47
  • 63
0
>>> import decimal, locale, re
>>> locale.setlocale(locale.LC_MONETARY, 'es_ES.UTF8')
>>> locale.setlocale(locale.LC_NUMERIC, 'es_ES.UTF8')
>>> locale.currency(6150593.22)
'6150593,22 €'
>>> re.sub('[^(\d,.)]', '', locale.currency(6150593.22))
'6150593,22'
>>> 6150593.22 == locale.atof(re.sub('[^(\d,.)]', '', locale.currency(6150593.22)))
True
>>> decimal.Decimal(locale.atof(re.sub('[^(\d,.)]', '', locale.currency(6150593.22))))
Decimal('6150593.219999999739229679107666015625')

Works as "revert what currency() did to my float" for a lot of locales I've tested.

Bonus: Converted do Decimal

Iuri Guilherme
  • 389
  • 1
  • 10