117

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]
martineau
  • 119,623
  • 25
  • 170
  • 301
static_rtti
  • 53,760
  • 47
  • 136
  • 192

19 Answers19

117

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.

martineau
  • 119,623
  • 25
  • 170
  • 301
Esteban Küber
  • 36,388
  • 15
  • 79
  • 97
  • 2
    This was the one I used but I added `.replace("'", "")` to get rid of those commas. `str(["{0:0.2f}".format(i) for i in a]).replace("'", "")` – Steinarr Jan 12 '17 at 15:51
  • 1
    This will produce a list of string. In the printed output, every element has `''` around it. For example, for `a=[0.2222, 0.3333]`, it will produce `['0.22', '0.33']`. – jdhao Dec 19 '17 at 15:14
  • To remove the apex and the commas, you should use `' '.join([{0:0.2f}".format(i) for i in a])` – Neb Aug 03 '18 at 08:25
82

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]

Robert Rossney
  • 94,622
  • 24
  • 146
  • 218
  • 1
    I would have thought there was a simpler solution, but your answer is clearly the best, since you're about the only one to actually answer my question. – static_rtti Oct 14 '09 at 17:41
  • 4
    He's the only one to actually answer your -edited- question. Not disparaging the answerer, but you can't clarify a question and then slight the rest of the answerers based on the information we were working with. – Jed Smith Oct 14 '09 at 18:42
  • 1
    My original question did mention that I considered a for loop was not a good solution (for me a list comprehension is the same, but I agree that wasn't clear). I'll try being clearer next time. – static_rtti Oct 15 '09 at 06:56
  • 3
    [f(n) for n in x] is much more pythonic than map(f, x). – Robert T. McGibbon Jun 12 '13 at 18:26
  • This seems dangerous to me. You add reference semantics to the floating type. This could have strange side-effects – lhk May 24 '16 at 11:12
  • 3
    I'm not necessarily in favor of subclassing float, but I don't think type checking is a valid argument. When checking types, `isinstance` should be used, not equality of `type()`. When it is done correctly, a subclass of float will still be counted as a float. – zondo Jan 04 '17 at 17:01
38

You can do:

a = [9.0, 0.052999999999999999, 0.032575399999999997, 0.010892799999999999, 0.055702500000000002, 0.079330300000000006]
print ["%0.2f" % i for i in a]
Pablo Santa Cruz
  • 176,835
  • 32
  • 241
  • 292
  • 5
    This will print ['9.00', '0.05', '0.03', '0.01', '0.06', '0.08'] - with quote marks, which you usually don't want (I prefer to have a valid list of floats printed) – Emile Oct 30 '15 at 09:39
30

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.

PlasmaBinturong
  • 2,122
  • 20
  • 24
26

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 
dalloliogm
  • 8,718
  • 6
  • 45
  • 55
  • 2
    -1 terrible hack. Join formatted pieces of strings, not other way around please – u0b34a0f6ae Oct 14 '09 at 16:07
  • 1
    so kaizer.se, are you proposing " ".join(["%.2f" % x for x in yourlist]) . I have having to do this kind of construction in python. – Gregg Lind Oct 14 '09 at 16:32
  • yes, I propose `" ".join("%.2f" % x for x in yourlist)` since parting format string and interpolation values is much worse than using an ugly Python idiom. – u0b34a0f6ae Oct 14 '09 at 19:00
  • It is curiosity. Why is tuple working while list fails? Without "tuple", it makes error. Why? – Joonho Park Jun 19 '20 at 03:07
20

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]
Markus Dutschke
  • 9,341
  • 4
  • 63
  • 58
10
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
Chikipowpow
  • 809
  • 8
  • 9
8
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]
fortran
  • 74,053
  • 25
  • 135
  • 175
8

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]
Rainald62
  • 706
  • 12
  • 19
4

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
ArtOfWarfare
  • 20,617
  • 19
  • 137
  • 193
Jed Smith
  • 15,584
  • 8
  • 52
  • 59
  • 5
    A generator expression would be even better: ", ".join("%.2f" % f for f in list_o_numbers) – efotinis Oct 14 '09 at 15:14
  • @efotinis Haven't added those to my repertoire yet, but you're right -- that's pretty sexy. – Jed Smith Oct 14 '09 at 15:16
  • 1
    @Jed: Please read the FAQ, section "Other people can edit my stuff?!": http://stackoverflow.com/faq. Not every edit is a good one, but this one was a genuine improvement. Perhaps you can list both techniques in your answer, and add a note about the difference? – Stephan202 Oct 16 '09 at 13:40
4

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

  • 1
    Python 3.1 will print the shortest decimal representation that maps to that float value. For example: >>>a, b = float(1.1), float(1.1000000000000001) >>>a 1.1000000000000001 >>>b 1.1000000000000001 >>>print(a,b) 1.1 1.1 – Matt Boehm Oct 17 '09 at 20:08
4

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<--
x0s
  • 1,648
  • 17
  • 17
3

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')
ifmihai
  • 79
  • 2
  • 6
2

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)
u0b34a0f6ae
  • 48,117
  • 14
  • 92
  • 101
2
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.

Kobap Bopy
  • 61
  • 8
2

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...

kitsu.eb
  • 2,996
  • 1
  • 26
  • 28
1

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)

Emile
  • 2,946
  • 2
  • 19
  • 22
0

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)
PTBNL
  • 6,042
  • 4
  • 28
  • 34
-1

The code below works nice to me.

list = map (lambda x: float('%0.2f' % x), list)
Romerito
  • 53
  • 8