[Tutor] commas on numeric input

eryksun eryksun at gmail.com
Wed Jun 26 15:20:41 CEST 2013


On Wed, Jun 26, 2013 at 2:23 AM, Peter Otten <__peter__ at web.de> wrote:
> Jim Mooney wrote:
>
>> I thought I read somewhere that Py3 can be set to accept commas as
>> part of numeric input, without needing to filter, but now I can't find
>> the reference. Is there such a feature, which would be useful, or did
>> I see it as part of some numeric module and misremember it?
>
> You can set a locale that recognizes the comma as thousands separator:
>
>>>> locale.setlocale(locale.LC_ALL, "en_US.UTF-8")
> 'en_US.UTF-8'
>>>> locale.atoi("1,234,567")
> 1234567
>>>> locale.atof("1,234.56")
> 1234.56

On Windows this locale is "enu_usa". You can also specify one of
Microsoft's code pages, such as 1252 (Western European):

    >>> locale.setlocale(locale.LC_NUMERIC, 'enu_usa.1252')
    'English_United States.1252'
    >>> locale.atof('1,234')
    1234.0

    >>> locale.setlocale(locale.LC_NUMERIC, 'deu_deu.1252')
    'German_Germany.1252'
    >>> locale.atof('1,234')
    1.234

There are variations allowed, such as "english_us", or the long form
that you see in the result, but generally you can use the 3-letter
language/country abbreviations in the last two columns of the table
found here:

http://msdn.microsoft.com/en-us/goglobal/bb896001

code pages:
http://msdn.microsoft.com/en-us/library/dd317756

Note that you can't use code page 65001 (UTF-8) in a locale setting.


As to the conversion, locale.atof() is simple enough to include here:

    def atof(string, func=float):
        "Parses a string as a float according to the locale settings."
        #First, get rid of the grouping
        ts = localeconv()['thousands_sep']
        if ts:
            string = string.replace(ts, '')
        #next, replace the decimal point with a dot
        dd = localeconv()['decimal_point']
        if dd:
            string = string.replace(dd, '.')
        #finally, parse the string
        return func(string)

    def atoi(str):
        "Converts a string to an integer according to the locale settings."
        return atof(str, int)


Notice the undocumented argument for the result type:

    >>> locale.atof('1,234', decimal.Decimal)
    Decimal('1234')
    >>> locale.atof('1,234', fractions.Fraction)
    Fraction(1234, 1)

I'd advise writing your own function instead of relying on an
undocumented argument.

For locale-aware formatting there's the 'n' code:

    >>> format(1234, 'n')  # like 'd'
    '1,234'
    >>> format(1234.1234, '.8n')  # like 'g'
    '1,234.1234'


More information about the Tutor mailing list