By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,626 Members | 1,146 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,626 IT Pros & Developers. It's quick & easy.

String formatting (%)

P: n/a
Hello,
I've a float number 123456789.01 and, I'de like to format it like this
"123 456 789.01".
Is this possible with % character?
Jul 18 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
Pascal wrote:
Hello,
I've a float number 123456789.01 and, I'de like to format it like this
"123 456 789.01".
Is this possible with % character?


No, as shown by http://docs.python.org/lib/typesseq-strings.html
but you could probably use the 'locale' module instead.

I suspect there's also a regular expression that could deal with
that, but I don't want to know what it is. ;-)

-Peter
Jul 18 '05 #2

P: n/a
Pascal,

Here is a function that I had that does what you want.
Warning-If the floats get very large it breaks down.

Larry Bates
Syscon, Inc.

def fmt_wspaces(amount):
#
# This function will take the number passed to it and format it with
# spaces as thousands separators.
#
# If I got zero return zero (0.00)
#
if not amount: return '0.00'
#
# Handle negative numbers
#
if amount < 0: sign="-"
else: sign=""
#
# Split into fractional and whole parts
#
whole_part=abs(long(amount))
fractional_part=abs(amount)-whole_part
#
# Convert to string
#
temp="%i" % whole_part
#
# Convert the digits to a list
#
digits=list(temp)
#
# Calculate the pad length to fill out a complete thousand and add
# the pad characters (space(s)) to the beginning of the string.
#
padchars=3-(len(digits)%3)
if padchars != 3: digits=tuple(padchars*[' ']+digits)
else: digits=tuple(digits)
#
# Create the mask for formatting the string
#
sections=len(digits)/3
mask=sections*" %s%s%s"
if _debug > 2: logf.writelines("D","mask=%s" % mask)
outstring=mask % digits
#
# Drop off the leading space and add back the sign
#
outstring=sign+outstring[1:].lstrip()
#
# Add back the fractional part
#
outstring+="%.2f" % fractional_part
#
return outstring

if __name__=="__main__":

print "----------testing negative floats------------------------------"
sign=-1
invalue=0L
for j in range(2):
for i in range(1,10):
invalue=invalue*10+i
print fmt_wspaces(float(sign*invalue)-.01)

print "----------testing positive floats------------------------------"
sign=1
invalue=0L
for j in range(2):
for i in range(1,10):
invalue=invalue*10+i
print fmt_wspaces(float(sign*invalue)+.01)

"Pascal" <pa***********@free.fr> wrote in message
news:e5**************************@posting.google.c om...
Hello,
I've a float number 123456789.01 and, I'de like to format it like this
"123 456 789.01".
Is this possible with % character?

Jul 18 '05 #3

P: n/a
Pascal wrote:
Hello,
I've a float number 123456789.01 and, I'de like to format it like this
"123 456 789.01".
Is this possible with % character?


The following should do what you want, although the commafy_float I
quickly added is probably a little naive:
def commafy(numstring, thousep=","):
"""
Commafy the given numeric string numstring

By default the thousands separator is a comma
"""
numlist = list(numstring)
numlist.reverse()
tmp = []
for i in range(0, len(numlist), 3):
tmp.append("".join(numlist[i:i+3]))
numlist = thousep.join(tmp)
numlist = list(numlist)
numlist.reverse()
return "".join(numlist)

def commafy_float(flStr, thousep=","):
whole, dec = flStr.split(".")
return ".".join([commafy(whole, thousep=thousep)
, dec])

if __name__ == "__main__":

units = "56746781250450"
unitsWithThouSeps = commafy(units)
print unitsWithThouSeps
aFloatAsString = "1128058.23"
aFloatAsStringWithThouSeps = commafy_float(aFloatAsString
,thousep=" ")
print aFloatAsStringWithThouSeps
Regards

-- Vincent Wehren
Jul 18 '05 #4

P: n/a
On Wed, 28 Apr 2004 09:15:02 -0400, Peter Hansen <pe***@engcorp.com>
wrote:
Pascal wrote:
Hello,
I've a float number 123456789.01 and, I'de like to format it like this
"123 456 789.01".
Is this possible with % character?


No, as shown by http://docs.python.org/lib/typesseq-strings.html
but you could probably use the 'locale' module instead.

I suspect there's also a regular expression that could deal with
that, but I don't want to know what it is. ;-)

-Peter

Since you don't want to know what it is, I'll at least tell you
where it is: In Mastering Regular Expressions by Jeffrey E. F. Friedl.
I don't have it front of me, but it's the "commafying" example. A
quick search of the author's site looks like it's on pgs 64-65.
Of course, the OP would substitute spaces for the commas.
--dang
Jul 18 '05 #5

P: n/a
Daniel 'Dang' Griffith wrote:
On Wed, 28 Apr 2004 09:15:02 -0400, Peter Hansen <pe***@engcorp.com>
wrote:
I suspect there's also a regular expression that could deal with
that, but I don't want to know what it is. ;-)
Since you don't want to know what it is, I'll at least tell you
where it is: In Mastering Regular Expressions by Jeffrey E. F. Friedl.
I don't have it front of me, but it's the "commafying" example. A
quick search of the author's site looks like it's on pgs 64-65.


Thank you. You can even get the code listings online, which is
very nice since my copy has migrated into a closet during a recent
move.
import re
s = '21421906.12'

re.sub(r'(?<=\d)(?=(\d\d\d)+\.)', ',', s) '21,421,906.12'
Of course, the OP would substitute spaces for the commas.

_.replace(',', ' ')

'21 421 906.12'

Very nice... quite elegant, I suppose. I struggled with it a
bit myself yesterday but I'm no RE expert. :-(

-Peter
Jul 18 '05 #6

P: n/a
pa***********@free.fr (Pascal) wrote in message news:<e5**************************@posting.google. com>...
Hello,
I've a float number 123456789.01 and, I'de like to format it like this
"123 456 789.01".
Is this possible with % character?


No, but this works with integers. Not sure how it compares to the
other approaches mentioned. You could adapt it to do floats by
stopping at the decimal point:

def addCommas(aNumber):
if len(aNumber) < 4: return aNumber
#how many digits before first ,?
prefix = len(aNumber) % 3
#need special case if digits is multiple of 3
if prefix == 0: prefix = 3
result = [aNumber[:prefix]]
for a in range(len(aNumber) / 3):
#get next 'segment' of three digits
segment = aNumber[prefix + 3*a: prefix + 3*a + 3]
if segment: #can be '' if len(aNumber) divisible by 3
result.append(segment)
return ','.join(result)

I'm sure this can be improved.
Jul 18 '05 #7

P: n/a
Peter Hansen wrote:
>>> import re
>>> s = '21421906.12'
>>>
>>> re.sub(r'(?<=\d)(?=(\d\d\d)+\.)', ',', s) '21,421,906.12'
Of course, the OP would substitute spaces for the commas.

>>> _.replace(',', ' ')

'21 421 906.12'


And in case the OP is entirely unfamiliar with regular
expressions, you wouldn't actually do a separate "replace"
operation like the above, so

re.sub(r'(?<=\d)(?=(\d\d\d)+\.)', ' ', s)

should work nicely, at least with any floating that *always*
has a decimal point present. If the numbers might sometimes
not have a decimal point, I think this will do the job, so
it's a more general solution:

re.sub(r'(?<=\d)(?=(\d\d\d)+(\.|$))', ' ', s)

Note that addition of an alternate for \. at the end of the pattern.

-Peter
Jul 18 '05 #8

P: n/a
On Wed, 28 Apr 2004 09:15:02 -0400, Peter Hansen <pe***@engcorp.com> wrote:
Pascal wrote:
Hello,
I've a float number 123456789.01 and, I'de like to format it like this
"123 456 789.01".
Is this possible with % character?


No, as shown by http://docs.python.org/lib/typesseq-strings.html
but you could probably use the 'locale' module instead.

I suspect there's also a regular expression that could deal with
that, but I don't want to know what it is. ;-)


If you are willing to use a special name mod (you can choose it), you
can get there with % and a commafy that stuffs spaces instead of commas ;-)
class Doit(dict): ... def __init__(self, d): dict.__init__(self, d)
... def __getitem__(self, name):
... if name.startswith('cfy_'):
... return commafy(self.get(name[4:],'??'))
... else: return self.get(name,'??')
... def commafy(val): ... sign, val = '-'[:val<0], str(abs(val))
... val, dec = (val.split('.')+[''])[:2]
... if dec: dec = '.'+dec
... rest = ''
... while val: val, rest = val[:-3], '%s %s'%(val[-3:], rest)
... return '%s%s%s' %(sign, rest[:-1], dec)
... x=1234
'x: %(x)s cfy_x: %(cfy_x)s' % Doit(vars()) 'x: 1234 cfy_x: 1 234' x=12345.678
'x: %(x)s cfy_x: %(cfy_x)s' % Doit(vars()) 'x: 12345.678 cfy_x: 12 345.678' x = -12345.678
'x: %(x)s cfy_x: %(cfy_x)s' % Doit(vars()) 'x: -12345.678 cfy_x: -12 345.678'

And the OP's example:
x = 123456789.01
'x: %(x)s cfy_x: %(cfy_x)s' % Doit(vars())

'x: 123456789.01 cfy_x: 123 456 789.01'

Regards,
Bengt Richter
Jul 18 '05 #9

P: n/a
al************@comcast.net (A. Lloyd Flanagan) wrote in message

Another version of a more compact function would be,

def commafy(s):
return len(s) > 3 and "%s,%s" % (commafy(s[:-3]), s[-3:]) or s

Note that this function accepts string representation of an integer
(without checks of course).

P Adhia
Jul 18 '05 #10

P: n/a
pa****@yahoo.com (P Adhia) wrote in message news:<32**************************@posting.google. com>...
Another version of a more compact function would be,

def commafy(s):
return len(s) > 3 and "%s,%s" % (commafy(s[:-3]), s[-3:]) or s

Note that this function accepts string representation of an integer
(without checks of course).

P Adhia


And it seeems to work beautifully. Thanks, that's a great improvement.
Jul 18 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.