|
Description:
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.
Source: Text Source
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.
|
|
Add comment
|
|
Number of comments: 2
Another solution, ralph heimburger, 2006/10/09
#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)
Add comment
Using locale, Tim Keating, 2007/11/05
FYI, the reason using locale didn't work is probably because you didn't set the locale first:
>>> locale.setlocale(locale.LC_ALL, "")
'English_United States.1252'
>>> locale.format('%d', 12345, True)
'12,345'
Counterintuitive, not well documented, non-Pythonic and just plain sucky, but there you go.
Add comment
|
|
|