Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Format string - spaces between every three digit

Tags:

python

How to simple format string with decimal number for show it with spaces between every three digits?

I can make something like this:

some_result = '12345678,46'
' '.join(re.findall('...?', test[:test.find(',')]))+test[test.find(','):]

and result is:

'123 456 78,46'

but I want:

'12 345 678,46'
like image 242
Lukasz Koziara Avatar asked Jul 05 '13 08:07

Lukasz Koziara


3 Answers

This is a bit hacky, but:

format(12345678.46, ',').replace(',', ' ').replace('.', ',')

As described in Format specification mini-language, in a format_spec:

The ',' option signals the use of a comma for a thousands separator.

Then we just replace each comma with a space, then the decimal point with a comma, and we're done.

For more complex cases using str.format instead of format, the format_spec goes after the colon, as in:

'{:,}'.format(12345678.46)

See PEP 378 for details.


Meanwhile, if you're just trying to use the standard grouping and separators for your system's locale, there are easier ways to do that—the n format type, or the locale.format function, etc. For example:

>>> locale.setlocale(locale.LC_NUMERIC, 'pl_PL')
>>> format(12345678, 'n')
12 345 678
>>> locale.format('%.2f' 12345678.12, grouping=True)
12 345 678,46
>>> locale.setlocale(locale.LC_NUMERIC, 'fr_FR')
>>> locale.format('%.2f' 12345678.12, grouping=True)
12345678,46
>>> locale.setlocale(locale.LC_ALL, 'en_AU')
>>> locale.format('%.2f' 12345678.12, grouping=True)
12,345,678.46

If your system locale is, say, pl_PL, just calling locale.setlocale(locale.LC_NUMERIC) (or locale.setlocale(locale.LC_ALL)) will pick up the Polish settings that you want, but the same person running your program in Australia will pick up the Australian settings that he wants.

like image 91
abarnert Avatar answered Sep 30 '22 19:09

abarnert


I think a regex would be much nicer:

>>> import re
>>> some_result = '12345678,46'
>>> re.sub(r"\B(?=(?:\d{3})+,)", " ", some_result)
'12 345 678,46'

Explanation:

\B       # Assert that we're not at the start of a number
(?=      # Assert that the following regex could match from here:
 (?:     # The following non-capturing group
  \d{3}  # which contains three digits
 )+      # and can be matched one or more times
 ,       # until a comma follows.
)        # End of lookahead assertion
like image 37
Tim Pietzcker Avatar answered Sep 30 '22 18:09

Tim Pietzcker


Use:

' '.join(re.findall('...?',test[:test.find(',')][::-1]))[::-1]+test[test.find(','):]

You have used regex which starts matching a string from the start. But you want to group the 3 numbers from the end (before comma).

So reverse the string before comma, apply the same logic and then reverse it back.

like image 27
Sudipta Avatar answered Sep 30 '22 19:09

Sudipta