Easy pretty printing of floats?

Question:

I have a list of floats. If I simply print it, it shows up like this:

[9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]

I could use print "%.2f", which would require a for loop to traverse the list, but then it wouldn’t work for more complex data structures.
I’d like something like (I’m completely making this up)

>>> import print_options
>>> print_options.set_float_precision(2)
>>> print [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]
[9.0, 0.05, 0.03, 0.01, 0.06, 0.08]
Asked By: static_rtti

||

Answers:

Note that you can also multiply a string like “%.2f” (example: “%.2f “*10).

>>> print "%.2f "*len(yourlist) % tuple(yourlist)
2.00 33.00 4.42 0.31 
Answered By: dalloliogm

List comps are your friend.

print ", ".join("%.2f" % f for f in list_o_numbers)

Try it:

>>> nums = [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999]
>>> print ", ".join("%.2f" % f for f in nums)
9.00, 0.05, 0.03, 0.01
Answered By: Jed Smith

You can do:

a = [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]
print ["%0.2f" % i for i in a]
Answered By: Pablo Santa Cruz

I believe that Python 3.1 will print them nicer by default, without any code changing. But that is useless if you use any extensions that haven’t been updated to work with Python 3.1

I agree with SilentGhost’s comment, the for loop isn’t that bad. You can achieve what you want with:

l = [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]
for x in l: print "%0.2f" % (x)
Answered By: PTBNL
print "[%s]"%", ".join(map(str,yourlist))

This will avoid the rounding errors in the binary representation when printed, without introducing a fixed precision constraint (like formating with "%.2f"):

[9.0, 0.053, 0.0325754, 0.0108928, 0.0557025, 0.0793303]
Answered By: fortran

As no one has added it, it should be noted that going forward from Python 2.6+ the recommended way to do string formating is with format, to get ready for Python 3+.

print ["{0:0.2f}".format(i) for i in a]

The new string formating syntax is not hard to use, and yet is quite powerfull.

I though that may be pprint could have something, but I haven’t found anything.

Answered By: Esteban Küber

First, elements inside a collection print their repr. you should learn about __repr__ and __str__.

This is the difference between print repr(1.1) and print 1.1. Let’s join all those strings instead of the representations:

numbers = [9.0, 0.053, 0.0325754, 0.0108928, 0.0557025, 0.07933]
print "repr:", " ".join(repr(n) for n in numbers)
print "str:", " ".join(str(n) for n in numbers)
Answered By: u0b34a0f6ae

A more permanent solution is to subclass float:

>>> class prettyfloat(float):
    def __repr__(self):
        return "%0.2f" % self

>>> x
[1.290192, 3.0002, 22.119199999999999, 3.4110999999999998]
>>> x = map(prettyfloat, x)
>>> x
[1.29, 3.00, 22.12, 3.41]
>>> y = x[2]
>>> y
22.12

The problem with subclassing float is that it breaks code that’s explicitly looking for a variable’s type. But so far as I can tell, that’s the only problem with it. And a simple x = map(float, x) undoes the conversion to prettyfloat.

Tragically, you can’t just monkey-patch float.__repr__, because float‘s immutable.

If you don’t want to subclass float, but don’t mind defining a function, map(f, x) is a lot more concise than [f(n) for n in x]

Answered By: Robert Rossney

I just ran into this problem while trying to use pprint to output a list of tuples of floats.
Nested comprehensions might be a bad idea, but here’s what I did:

tups = [
        (12.0, 9.75, 23.54),
        (12.5, 2.6, 13.85),
        (14.77, 3.56, 23.23),
        (12.0, 5.5, 23.5)
       ]
pprint([['{0:0.02f}'.format(num) for num in tup] for tup in tups])

I used generator expressions at first, but pprint just repred the generator…

Answered By: kitsu.eb

You could use pandas.

Here is an example with a list:

In: import pandas as P
In: P.set_option('display.precision',3)
In: L = [3.4534534, 2.1232131, 6.231212, 6.3423423, 9.342342423]
In: P.Series(data=L)
Out: 
0    3.45
1    2.12
2    6.23
3    6.34
4    9.34
dtype: float64

If you have a dict d, and you want its keys as rows:

In: d
Out: {1: 0.453523, 2: 2.35423234234, 3: 3.423432432, 4: 4.132312312}

In: P.DataFrame(index=d.keys(), data=d.values())
Out:  
    0
1   0.45
2   2.35
3   3.42
4   4.13

And another way of giving dict to a DataFrame:

P.DataFrame.from_dict(d, orient='index')
Answered By: ifmihai

I had this problem, but none of the solutions here did exactly what I wanted (I want the printed output to be a valid python expression), so how about this:

prettylist = lambda l : '[%s]' % ', '.join("%.2f" % f for f in l)

Usage:

>>> ugly = [9.0, 0.052999999999999999, 0.032575399999999997,
            0.010892799999999999, 0.055702500000000002, 0.079330300000000006]
>>> prettylist = lambda l : '[%s]' % ', '.join("%.2f" % f for f in l)
>>> print prettylist(ugly)
[9.00, 0.05, 0.03, 0.01, 0.06, 0.08]

(I know .format() is supposed to be the more standard solution, but I find this more readable)

Answered By: Emile

The code below works nice to me.

list = map (lambda x: float('%0.2f' % x), list)
Answered By: Romerito
l = [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]

Python 2:

print ', '.join('{:0.2f}'.format(i) for i in l)

Python 3:

print(', '.join('{:0.2f}'.format(i) for i in l))

Output:

9.00, 0.05, 0.03, 0.01, 0.06, 0.08
Answered By: Chikipowpow

The most easy option should be to use a rounding routine:

import numpy as np
x=[9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]

print('standard:')
print(x)
print("nhuman readable:")
print(np.around(x,decimals=2))

This produces the output:

standard:
[9.0, 0.053, 0.0325754, 0.0108928, 0.0557025, 0.0793303]

human readable:
[ 9.    0.05  0.03  0.01  0.06  0.08]
Answered By: Markus Dutschke

To control the number of significant digits, use the format specifier %g.

Let’s name Emile’s solution prettylist2f. Here is the modified one:

prettylist2g = lambda l : '[%s]' % ', '.join("%.2g" % x for x in l)

Usage:

>>> c_e_alpha_eps0 = [299792458., 2.718281828, 0.00729735, 8.8541878e-12]
>>> print(prettylist2f(c_e_alpha_eps0)) # [299792458.00, 2.72, 0.01, 0.00]
>>> print(prettylist2g(c_e_alpha_eps0)) # [3e+08, 2.7, 0.0073, 8.9e-12]

If you want flexibility in the number of significant digits, use f-string formatting instead:

prettyflexlist = lambda p, l : '[%s]' % ', '.join(f"{x:.{p}}" for x in l)
print(prettyflexlist(3,c_e_alpha_eps0)) # [3e+08, 2.72, 0.0073, 8.85e-12]
Answered By: Rainald62

As of Python 3.6, you can use f-strings:

list_ = [9.0, 0.052999999999999999, 
         0.032575399999999997, 0.010892799999999999, 
         0.055702500000000002, 0.079330300000000006]

print(*[f"{element:.2f}" for element in list_])
#9.00 0.05 0.03 0.01 0.06 0.08

You can use print parameters while keeping code very readable:

print(*[f"{element:.2f}" for element in list_], sep='|', end='<--')
#9.00|0.05|0.03|0.01|0.06|0.08<--
Answered By: x0s

It’s an old question but I’d add something potentially useful:

I know you wrote your example in raw Python lists, but if you decide to use numpy arrays instead (which would be perfectly legit in your example, because you seem to be dealing with arrays of numbers), there is (almost exactly) this command you said you made up:

import numpy as np
np.set_printoptions(precision=2)

Or even better in your case if you still want to see all decimals of really precise numbers, but get rid of trailing zeros for example, use the formatting string %g:

np.set_printoptions(formatter={"float_kind": lambda x: "%g" % x})

For just printing once and not changing global behavior, use np.array2string with the same arguments as above.

Answered By: PlasmaBinturong
a = [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]
print(", ".join(f'{x:.2f}' for x in a))

f'{x}' means f-string equal to str(x); f'{x:.2f}' means x will be present as float number with two decimal places.

Answered By: Kobap Bopy