If you are using it in a formatted string with the format() method which is preferred over the older style ''% formatting
>>> 'One hundred and twenty three with three leading zeros {0:06}.'.format(123)
'One hundred and twenty three with three leading zeros 000123.'
See
http://docs.python.org/library/stdtypes.html#str.format
http://docs.python.org/library/string.html#formatstrings
Here is an example with variable width
>>> '{num:0{width}}'.format(num=123, width=6)
'000123'
You can even specify the fill char as a variable
>>> '{num:{fill}{width}}'.format(num=123, fill='0', width=6)
'000123'
Answer from John La Rooy on Stack OverflowVideos
If you are using it in a formatted string with the format() method which is preferred over the older style ''% formatting
>>> 'One hundred and twenty three with three leading zeros {0:06}.'.format(123)
'One hundred and twenty three with three leading zeros 000123.'
See
http://docs.python.org/library/stdtypes.html#str.format
http://docs.python.org/library/string.html#formatstrings
Here is an example with variable width
>>> '{num:0{width}}'.format(num=123, width=6)
'000123'
You can even specify the fill char as a variable
>>> '{num:{fill}{width}}'.format(num=123, fill='0', width=6)
'000123'
There is a string method called zfill:
>>> '12344'.zfill(10)
0000012344
It will pad the left side of the string with zeros to make the string length N (10 in this case).
numbers = [23.23, 0.1233, 1.0, 4.223, 9887.2]
for x in numbers:
print("{:10.4f}".format(x))
prints
23.2300
0.1233
1.0000
4.2230
9887.2000
The format specifier inside the curly braces follows the Python format string syntax. Specifically, in this case, it consists of the following parts:
- The empty string before the colon means "take the next provided argument to
format()" โ in this case thexas the only argument. - The
10.4fpart after the colon is the format specification. - The
fdenotes fixed-point notation. - The
10is the total width of the field being printed, lefted-padded by spaces. - The
4is the number of digits after the decimal point.
It has been a few years since this was answered, but as of Python 3.6 (PEP498) you could use the new f-strings:
numbers = [23.23, 0.123334987, 1, 4.223, 9887.2]
for number in numbers:
print(f'{number:9.4f}')
Prints:
23.2300
0.1233
1.0000
4.2230
9887.2000
Starting with Python 3.6, formatting in Python can be done using formatted string literals or f-strings:
hours, minutes, seconds = 6, 56, 33
f'{hours:02}:{minutes:02}:{seconds:02} {"pm" if hours > 12 else "am"}'
or the str.format function starting with 2.7:
"{:02}:{:02}:{:02} {}".format(hours, minutes, seconds, "pm" if hours > 12 else "am")
or the string formatting % operator for even older versions of Python, but see the note in the docs:
"%02d:%02d:%02d" % (hours, minutes, seconds)
And for your specific case of formatting time, thereโs time.strftime:
import time
t = (0, 0, 0, hours, minutes, seconds, 0, 0, 0)
time.strftime('%I:%M:%S %p', t)
The OP & accepted answer focus on formatting time, but the OP question itself discusses formatting numbers to strings in Python. In many cases, the output requires additional data fields be included along with timestamps, all of which include formatting numbers as strings.
Below are a variety of non time-based examples of formatting numbers as strings, and different ways to do so, starting with the existing string format operator (%) which has been around for as long as Python has been around (meaning this solution is compatible across Python 1.x, 2.x, and 3.x):
>>> "Name: %s, age: %d" % ('John', 35)
'Name: John, age: 35'
>>> i = 45
>>> 'dec: %d/oct: %#o/hex: %#X' % (i, i, i)
'dec: 45/oct: 055/hex: 0X2D'
>>> "MM/DD/YY = %02d/%02d/%02d" % (12, 7, 41)
'MM/DD/YY = 12/07/41'
>>> 'Total with tax: $%.2f' % (13.00 * 1.0825)
'Total with tax: $14.07'
>>> d = {'web': 'user', 'page': 42}
>>> 'http://xxx.yyy.zzz/%(web)s/%(page)d.html' % d
'http://xxx.yyy.zzz/user/42.html'
Starting in Python 2.6 (meaning it works for 2.x and 3.x), there is an alternative: the str.format() method. Here are the equivalent snippets to the above but using str.format():
>>> "Name: {0}, age: {1}".format('John', 35)
'Name: John, age: 35'
>>> i = 45
>>> 'dec: {0}/oct: {0:#o}/hex: {0:#X}'.format(i)
'dec: 45/oct: 0o55/hex: 0X2D'
>>> "MM/DD/YY = {0:02d}/{1:02d}/{2:02d}".format(12, 7, 41)
'MM/DD/YY = 12/07/41'
>>> 'Total with tax: ${0:.2f}'.format(13.00 * 1.0825)
'Total with tax: $14.07'
>>> d = {'web': 'user', 'page': 42}
>>> 'http://xxx.yyy.zzz/{web}/{page}.html'.format(**d)
'http://xxx.yyy.zzz/user/42.html'
Like Python 2.6+, all Python 3 releases (so far) understand how to do both. I shamelessly ripped this stuff straight out of my hardcore Python intro book and the slides for the Intro+Intermediate Python courses I offer from time-to-time. :-)
Aug 2018 UPDATE: Of course, now that we have the f-string feature introduced in 3.6 (only works in 3.6 and newer), we need the equivalent examples of that; yes, another alternative:
>>> name, age = 'John', 35
>>> f'Name: {name}, age: {age}'
'Name: John, age: 35'
>>> i = 45
>>> f'dec: {i}/oct: {i:#o}/hex: {i:#X}'
'dec: 45/oct: 0o55/hex: 0X2D'
>>> m, d, y = 12, 7, 41
>>> f"MM/DD/YY = {m:02d}/{d:02d}/{y:02d}"
'MM/DD/YY = 12/07/41'
>>> f'Total with tax: ${13.00 * 1.0825:.2f}'
'Total with tax: $14.07'
>>> d = {'web': 'user', 'page': 42}
>>> f"http://xxx.yyy.zzz/{d['web']}/{d['page']}.html"
'http://xxx.yyy.zzz/user/42.html'
The new format string syntax allows you to use format specifiers, just like the old %-based syntax. The format specifiers you can use are similar, not exactly the same in all cases (I think), but as far as I know, anything you could do with the old syntax can also be done with the new syntax.
All you have to do is put the format specifier inside the formatting expression, separated from the field name/number by a colon. In this case, you could use {value1:02d}, where 02d is the code to get a zero-filled (0) width-2 (2) representation of an integer (d).
print("{0:02}".format(1))
>>0001
Just learnt from other answers and commentators that we don't need zfill but can use the expression :02 to give the padding.
Expand to more positions:
print("{0:02}_{1:02}".format(1, 2))
>>0001_0002
Just by using your example,
a = 1234.567890123
b = 12345.678901234
str(a)[:8] # gives '1234.567'
str(b)[:8] # gives '12345.67'
The simplest solution is probably to use the exponential format with one less than the number of digits.
"{0:.6e}".format(1234.457890123) = '1.234568e+03'
I ended up writing this solution that can print floats as well as exponentials but it's probably unnecessarily long for most needs.
import numpy as np
def sigprint(number,nsig):
"""
Returns a string with the given number of significant digits.
For numbers >= 1e5, and less than 0.001, it does exponential notation
This is almost what ":.3g".format(x) does, but in the case
of '{:.3g}'.format(2189), we want 2190 not 2.19e3. Also in the case of
'{:.3g}'.format(1), we want 1.00, not 1
"""
if ((abs(number) >= 1e-3) and (abs(number) < 1e5)) or number ==0:
place = decplace(number) - nsig + 1
decval = 10**place
outnum = np.round(np.float(number) / decval) * decval
## Need to get the place again in case say 0.97 was rounded up to 1.0
finalplace = decplace(outnum) - nsig + 1
if finalplace >= 0: finalplace=0
fmt='.'+str(int(abs(finalplace)))+'f'
else:
stringnsig = str(int(nsig-1))
fmt = '.'+stringnsig+'e'
outnum=number
wholefmt = "{0:"+fmt+"}"
return wholefmt.format(outnum)
def decplace(number):
"""
Finds the decimal place of the leading digit of a number. For 0, it assumes
a value of 0 (the one's digit)
"""
if number == 0:
place = 0
else:
place = np.floor(np.log10(np.abs(number)))
return place