Needed formatted numbers with thousands separator commas added on an end-user report. The usual way mentioned is to use 'module locale.format', but that didn't work cleanly on my Windows machine, and the cure seemed worse than the disease.
| Python |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | import re
__test__ = {}
re_digits_nondigits = re.compile(r'\d+|\D+')
__test__['re_digits_nondigits'] = r"""
>>> re_digits_nondigits.findall('$1234.1234')
['$', '1234', '.', '1234']
>>> re_digits_nondigits.findall('1234')
['1234']
>>> re_digits_nondigits.findall('')
[]
"""
def FormatWithCommas(format, value):
"""
>>> FormatWithCommas('%.4f', .1234)
'0.1234'
>>> FormatWithCommas('%i', 100)
'100'
>>> FormatWithCommas('%.4f', 234.5678)
'234.5678'
>>> FormatWithCommas('$%.4f', 234.5678)
'$234.5678'
>>> FormatWithCommas('%i', 1000)
'1,000'
>>> FormatWithCommas('%.4f', 1234.5678)
'1,234.5678'
>>> FormatWithCommas('$%.4f', 1234.5678)
'$1,234.5678'
>>> FormatWithCommas('%i', 1000000)
'1,000,000'
>>> FormatWithCommas('%.4f', 1234567.5678)
'1,234,567.5678'
>>> FormatWithCommas('$%.4f', 1234567.5678)
'$1,234,567.5678'
>>> FormatWithCommas('%i', -100)
'-100'
>>> FormatWithCommas('%.4f', -234.5678)
'-234.5678'
>>> FormatWithCommas('$%.4f', -234.5678)
'$-234.5678'
>>> FormatWithCommas('%i', -1000)
'-1,000'
>>> FormatWithCommas('%.4f', -1234.5678)
'-1,234.5678'
>>> FormatWithCommas('$%.4f', -1234.5678)
'$-1,234.5678'
>>> FormatWithCommas('%i', -1000000)
'-1,000,000'
>>> FormatWithCommas('%.4f', -1234567.5678)
'-1,234,567.5678'
>>> FormatWithCommas('$%.4f', -1234567.5678)
'$-1,234,567.5678'
"""
parts = re_digits_nondigits.findall(format % (value,))
for i in xrange(len(parts)):
s = parts[i]
if s.isdigit():
parts[i] = _commafy(s)
break
return ''.join(parts)
def _commafy(s):
r = []
for i, c in enumerate(reversed(s)):
if i and (not (i % 3)):
r.insert(0, ',')
r.insert(0, c)
return ''.join(r)
|
Discussion
The recipe works by adding commas to the first contiguous group of digits. It could fail with some odd-ball format that puts extra digits before the number.






Comments
Another solution. #this solution uses the re module and a single function.
import re def currency(amount): temp = "%.2f" % amount profile=re.compile(r"(\d)(\d\d\d[.,])") while 1: temp, count = re.subn(profile,r"\1,\2",temp) if not count: break return '$'+temp
if __name__ == "__main__": print currency(3458905.54) print currency(-49786002.40)
Using locale. FYI, the reason using locale didn't work is probably because you didn't set the locale first:
Counterintuitive, not well documented, non-Pythonic and just plain sucky, but there you go.
Sign in to comment