def intToStringWithCommas(x):if type(x) is not int and type(x) is not long:raise TypeError("Not an integer!")if x < 0:return '-' + intToStringWithCommas(-x)elif x < 1000:return str(x)else:return intToStringWithCommas(x / 1000) + ',' + '%03d' % (x % 1000)
def intWithCommas(x):if type(x) not in [type(0), type(0L)]:raise TypeError("Parameter must be an integer.")if x < 0:return '-' + intWithCommas(-x)result = ''while x >= 1000:x, r = divmod(x, 1000)result = ",%03d%s" % (r, result)return "%d%s" % (x, result)
>>> class number(long):
def __init__(self, value):self = value
def __repr__(self):s = str(self)l = [x for x in s if x in '1234567890']for x in reversed(range(len(s)-1)[::3]):l.insert(-x, ',')l = ''.join(l[1:])return ('-'+l if self < 0 else l)
>>> number(-100000)-100,000>>> number(-100)-100>>> number(-12345)-12,345>>> number(928374)928,374>>> 345
def float2comma(f):s = str(abs(f)) # Convert to a stringdecimalposition = s.find(".") # Look for decimal pointif decimalposition == -1:decimalposition = len(s) # If no decimal, then just work from the endout = ""for i in range(decimalposition+1, len(s)): # do the decimalif not (i-decimalposition-1) % 3 and i-decimalposition-1: out = out+","out = out+s[i]if len(out):out = "."+out # add the decimal point if necessaryfor i in range(decimalposition-1,-1,-1): # working backwards from decimal pointif not (decimalposition-i-1) % 3 and decimalposition-i-1: out = ","+outout = s[i]+outif f < 0:out = "-"+outreturn out
>>> import itertools>>> s = '-1234567'>>> ','.join(["%s%s%s" % (x[0], x[1] or '', x[2] or '') for x in itertools.izip_longest(s[::-1][::3], s[::-1][1::3], s[::-1][2::3])])[::-1].replace('-,','-')
'{:,}'.format(value) # For Python ≥2.7f'{value:,}' # For Python ≥3.6
区域感知
import localelocale.setlocale(locale.LC_ALL, '') # Use '' for auto, or force e.g. to 'en_US.UTF-8'
'{:n}'.format(value) # For Python ≥2.7f'{value:n}' # For Python ≥3.6
from __future__ import with_statementfrom contextlib import contextmanagerimport re,time
re_first_num = re.compile(r"\d")def intcomma_noregex(value):end_offset, start_digit, period = len(value),re_first_num.search(value).start(),value.rfind('.')if period == -1:period=end_offsetsegments,_from_index,leftover = [],0,(period-start_digit) % 3for _index in xrange(start_digit+3 if not leftover else start_digit+leftover,period,3):segments.append(value[_from_index:_index])_from_index=_indexif not segments:return valuesegments.append(value[_from_index:])return ','.join(segments)
def intcomma_noregex_reversed(value):end_offset, start_digit, period = len(value),re_first_num.search(value).start(),value.rfind('.')if period == -1:period=end_offset_from_index,segments = end_offset,[]for _index in xrange(period-3,start_digit,-3):segments.append(value[_index:_from_index])_from_index=_indexif not segments:return valuesegments.append(value[:_from_index])return ','.join(reversed(segments))
re_3digits = re.compile(r'(?<=\d)\d{3}(?!\d)')def intcomma(value):segments,last_endoffset=[],len(value)while last_endoffset > 3:digit_group = re_3digits.search(value,0,last_endoffset)if not digit_group:breaksegments.append(value[digit_group.start():last_endoffset])last_endoffset=digit_group.start()if not segments:return valueif last_endoffset:segments.append(value[:last_endoffset])return ','.join(reversed(segments))
def intcomma_recurs(value):"""Converts an integer to a string containing commas every three digits.For example, 3000 becomes '3,000' and 45000 becomes '45,000'."""new = re.sub("^(-?\d+)(\d{3})", '\g<1>,\g<2>', str(value))if value == new:return newelse:return intcomma(new)
@contextmanagerdef timed(save_time_func):begin=time.time()try:yieldfinally:save_time_func(time.time()-begin)
def testset_xsimple(func):func('5')
def testset_simple(func):func('567')
def testset_onecomma(func):func('567890')
def testset_complex(func):func('-1234567.024')
def testset_average(func):func('-1234567.024')func('567')func('5674')
if __name__ == '__main__':print 'Test results:'for test_data in ('5','567','1234','1234.56','-253892.045'):for func in (intcomma,intcomma_noregex,intcomma_noregex_reversed,intcomma_recurs):print func.__name__,test_data,func(test_data)times=[]def overhead(x):passfor test_run in xrange(1,4):for func in (intcomma,intcomma_noregex,intcomma_noregex_reversed,intcomma_recurs,overhead):for testset in (testset_xsimple,testset_simple,testset_onecomma,testset_complex,testset_average):for x in xrange(1000): # prime the testtestset(func)with timed(lambda x:times.append(((test_run,func,testset),x))):for x in xrange(50000):testset(func)for (test_run,func,testset),_delta in times:print test_run,func.__name__,testset.__name__,_delta
re.sub(pattern, repl, string)
pattern = \"(\d) # Find one digit...(?= # that is followed by...(\d{3})+ # one or more groups of three digits...(?!\d) # which are not followed by any more digits.)",
repl = \r"\1,", # Replace that one digit by itself, followed by a comma,# and continue looking for more matches later in the string.# (re.sub() replaces all matches it finds in the input)
string = \"%d" % val # Format the string as a decimal to begin with
def ncomma(num):def _helper(num):# assert isinstance(numstr, basestring)numstr = '%d' % numfor ii, digit in enumerate(reversed(numstr)):if ii and ii % 3 == 0 and digit.isdigit():yield ','yield digit
return ''.join(reversed([n for n in _helper(num)]))
这里有一个测试:
>>> for i in (0, 99, 999, 9999, 999999, 1000000, -1, -111, -1111, -111111, -1000000):... print i, ncomma(i)...0 099 99999 9999999 9,999999999 999,9991000000 1,000,000-1 -1-111 -111-1111 -1,111-111111 -111,111-1000000 -1,000,000
def format_number_using_generators_and_list_comprehensions(number):string = '%d' % numbergenerator = reversed([value+',' if (index!=0 and value!='-' and index%3==0) else valuefor index,value in enumerate(reversed(string))])return ''.join(generator)
num = 2437.68
# Way 1: String Formatting
'{:,}'.format(num)>>> '2,437.68'
# Way 2: F-Strings
f'{num:,}'>>> '2,437.68'
# Way 3: Built-in Format Function
format(num, ',')>>> '2,437.68'