4

In Python 3.5, I'd like to convert a German number string to a float using locale.atof with the following code:


import locale
from locale import atof
locale.setlocale(locale.LC_ALL, 'de_DE')

number = atof('17.907,08')

However, this raises a ValueError:

ValueError: could not convert string to float: '17.907.08'


Why? Isn't this exactly what atof() was made for?
Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
Jan
  • 42,290
  • 8
  • 54
  • 79

3 Answers3

6

You can't have more than one dot (.) or comma (,) in your number since both of these symbols are used by atof() to separate the decimal part of your number from its integer part.

Since the dots are not needed for Python to correctly represent your number, you should remove them and only keep the comma:

import locale
from locale import atof
locale.setlocale(locale.LC_ALL, 'de_DE')

string_nb = '17.907,08'
string_nb = string_nb.replace('.', '')
number = atof(string)
Ronan Boiteau
  • 9,608
  • 6
  • 34
  • 56
  • It works and answers my question - but how to distinguish which part to remove? I have several numbers, English and German ones. – Jan Feb 17 '18 at 16:19
  • 1
    @Jan: What is the difference between English and German numbers? Does `17.907,08` in German become `17,907.08` in English? Or `17907.08`? – Ronan Boiteau Feb 17 '18 at 16:29
  • `$1,000,000` is one million in English while it would be `1.000.000` in German. – Jan Feb 17 '18 at 17:03
  • 2
    In Python 3.10 this manipulation is no longer needed. `atof('17.907,08')` works. – Panagiotis Kanavos May 13 '22 at 08:35
1

Just for future reference - this is what I ended up using:

import locale
from locale import atof

def convert(string, thousands_delim = '.', abbr = 'de_DE.UTF-8'):
    ''' Converts a string to float '''

    locale.setlocale(locale.LC_ALL, abbr)
    try:
        number = atof("".join(string.split(thousands_delim)))
    except ValueError:
        number = None

    return number


You call it like
number = convert('17.907,08')
print(number)
# 17907.08

... or for English numbers:

number = convert('1,000,000', abbr = 'en_US')
print(number)
# 1000000.0
Jan
  • 42,290
  • 8
  • 54
  • 79
0

In Python 3.10 the works as expected

>>> from locale import atof
>>> import locale
>>> locale.setlocale( locale.LC_ALL, 'de_DE' )
'de_DE'
>>> atof('17.907,08')
17907.08

Using string manipulations to parse decimals is very fragile and should be avoided when possible. Using the wrong replacement could convert decimals to thousands and vice versa

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236