484

How do I format a floating number to a fixed width with the following requirements:

  1. Leading zero if n < 1
  2. Add trailing decimal zero(s) to fill up fixed width
  3. Truncate decimal digits past fixed width
  4. Align all decimal points

For example:

% formatter something like '{:06}'
numbers = [23.23, 0.123334987, 1, 4.223, 9887.2]

for number in numbers:
    print formatter.format(number)

The output would be like

  23.2300
   0.1233
   1.0000
   4.2230
9887.2000
hobbes3
  • 28,078
  • 24
  • 87
  • 116

10 Answers10

690
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 the x as the only argument.
  • The 10.4f part after the colon is the format specification.
  • The f denotes fixed-point notation.
  • The 10 is the total width of the field being printed, lefted-padded by spaces.
  • The 4 is the number of digits after the decimal point.
Nico Schlömer
  • 53,797
  • 27
  • 201
  • 249
Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • 13
    So I understand that the 4f represents limiting the decimals to 4 (with trailing zeros), but what does the 10 mean? Does that mean this formatting won't work with integers greater than 9999999999 (ten 9's)? Just curious. – hobbes3 Jan 16 '12 at 20:17
  • 66
    `10.4` means a width of 10 characters and a precision of 4 decimal places. – MRAB Jan 16 '12 at 20:27
  • 15
    @hobbes3: `10` is the minimum field width, i.e. the minimum length of the printed string. Numbers are by default right-aligned and padded with spaces -- see [the documentation](http://docs.python.org/library/string.html#format-specification-mini-language) for more details. – Sven Marnach Jan 16 '12 at 20:27
  • 9
    For Pythons prior to 2.7: `("%0.4f" % x).rjust(10)` – Steven Rumbalski Jan 16 '12 at 21:26
  • 23
    @StevenRumbalski: Or simply `"%10.4f" % x`. In Python 2.6, you can also use `"{0:10.4f}".format(x)`. – Sven Marnach Jan 16 '12 at 21:33
  • 1
    That 10.4 means `12345.7890` and not `1234567890.0000` is the ghost of FORTRAN. Almost as old a curse as QWERTY. – Bob Stein Sep 15 '15 at 17:07
  • 1
    This doesn't work for negative floats though - the sign offsets the decimal column. Adding a leading space works though: `("% 10.4f" % x)`, or `"{: 10.4f}".format(x)` – naught101 Apr 21 '17 at 03:09
  • 1
    @naught101 Not sure what you mean; the code in this answer [works perferctly fine for negative numbers](https://ideone.com/Vq5MCY). – Sven Marnach Apr 21 '17 at 11:13
  • @SvenMarnach Ah, yeah, I read the docs wrong. The 10 is the total length, so it does work in this case. I had a case last week where it wasn't working, but it's because I was using the wrong number before the `.`. Still, the space adds a leading space to positive numbers, which may be useful, although I can't think of an example right now.. – naught101 Apr 24 '17 at 00:14
  • If numbers include signed floats then the floating point doesn't stay at the same column. Is there a way to also consider the negative sign? – PouJa Dec 05 '18 at 10:46
  • 1
    @PouJa The sign does not affect the position of the decimal point ([example](https://ideone.com/TP3QvH)). The only problem that can occur is that the number does not fit within the total width you alotted for it, in which case you should increase that number (`10` in the code above). – Sven Marnach Dec 05 '18 at 12:55
  • warning, this doesn't work with very large numbers, for example `print("{:10.10000f}".format(math.sqrt(666))[99])` prints 0, but that's not correct, it's supposed to be 1. and [100] prints prints 0, that's also wrong, [100] is supposed to be 9. – hanshenrik Nov 29 '21 at 15:16
  • @hanshenrik This is due to the limited precision of floating-point numbers. I'ts not related to how formatting works. In other words, `math.sqrt(666)` is only an approximation to the actual square root of 666. This approaximation is then exactly represented during string formatting. The 99. and 100. decimal place of the approximation actually are exactly 0. – Sven Marnach Nov 29 '21 at 15:24
224

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
Ryabchenko Alexander
  • 10,057
  • 7
  • 56
  • 88
artomason
  • 3,625
  • 5
  • 20
  • 43
  • 10
    Note that the width also includes dot character. So if you specify 9 to be width, 1 will be used for printing the dot, the other 8 will be for printing digits and spaces. – off99555 Jun 08 '19 at 20:32
49

In python3 the following works:

>>> v=10.4
>>> print('% 6.2f' % v)
  10.40
>>> print('% 12.1f' % v)
        10.4
>>> print('%012.1f' % v)
0000000010.4
Scott Roberts
  • 1,009
  • 8
  • 14
  • 1
    This has changed in the last 4 years, now `%` formatting is the oldest method of formatting. For several reasons using `str.format` or `f-strings` is preferred over `%`. Previously when it was only `str.format`, people had some reasons but `f-strings` fixed that hole. [format mini-language docs](https://docs.python.org/3/library/string.html#format-specification-mini-language), [str.format examples from docs](https://docs.python.org/3/library/string.html#format-examples) and [f-string literals examples in docs](https://docs.python.org/3/reference/lexical_analysis.html#formatted-string-literals) – ninMonkey Oct 01 '19 at 16:29
13

You can also left pad with zeros. For example if you want number to have 9 characters length, left padded with zeros use:

print('{:09.3f}'.format(number))

Thus, if number = 4.656, the output is: 00004.656

For your example the output will look like this:

numbers  = [23.2300, 0.1233, 1.0000, 4.2230, 9887.2000]
for x in numbers: 
    print('{:010.4f}'.format(x))

prints:

00023.2300
00000.1233
00001.0000
00004.2230
09887.2000

One example where this may be useful is when you want to properly list filenames in alphabetical order. I noticed in some linux systems, the number is: 1,10,11,..2,20,21,...

Thus if you want to enforce the necessary numeric order in filenames, you need to left pad with the appropriate number of zeros.

elcymon
  • 431
  • 4
  • 5
12

See Python 3.x format string syntax:

IDLE 3.5.1   
numbers = ['23.23', '.1233', '1', '4.223', '9887.2']

for x in numbers:  
    print('{0: >#016.4f}'. format(float(x)))  

     23.2300
      0.1233
      1.0000
      4.2230
   9887.2000
approxiblue
  • 6,982
  • 16
  • 51
  • 59
readyleader
  • 121
  • 1
  • 4
12

Using f-string literals:

>>> number = 12.34
>>> print(f"{number}")
12.34
>>> print(f"{number:10f}")
 12.340000
>>> print(f"{number:10.4f}")
   12.3400

The 10.4f after the colon : is the format specification, with 10 being the width in characters of the whole number (including spaces), and the second number 4 being the number of decimal places, and the f standing for floating-point number.

It's also possible to use variables instead of hard-coding the width and the number of decimal places:

>>> number = 12.34
>>> width = 10
>>> decimals = 4
>>> print(f"{number:{width}.{decimals}f}")
   12.3400
Flimm
  • 136,138
  • 45
  • 251
  • 267
10

This will print 76.66:

print("Number: ", f"{76.663254: .2f}")
Jimothy
  • 9,150
  • 5
  • 30
  • 33
Matt
  • 101
  • 1
  • 2
4

In Python 3.

GPA = 2.5
print(" %6.1f " % GPA)

6.1f means after the dots 1 digits show if you print 2 digits after the dots you should only %6.2f such that %6.3f 3 digits print after the point.

Dawny33
  • 10,543
  • 21
  • 82
  • 134
Usman Zia
  • 51
  • 4
1

I needed something similar for arrays. That helped me

some_array_rounded=np.around(some_array, 5)
David Buck
  • 3,752
  • 35
  • 31
  • 35
Anton
  • 61
  • 6
-1

I tried all the options like

  1. pd.options.display.float_format = '{:.4f}'.format
  2. pd.set_option('display.float_format', str)
  3. pd.set_option('display.float_format', lambda x: f'%.{len(str(x%1))-2}f' % x)
  4. pd.set_option('display.float_format', lambda x: '%.3f' % x)

but nothing worked for me.

so while assigning the variable/value (var1) to a variable (say num1) I used round(val,5) like

num1 = round(var1,5)

This is a crude method as you have to use this round function in each assignment. But this ensures you control on how it happens and get what you want.

Peter Csala
  • 17,736
  • 16
  • 35
  • 75