views:

731

answers:

9

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", but that would require a for loop to traverse the list, which I consider to be ugly. I believe that there must be a better solution.

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]
+6  A: 

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
very elegant! I like it
Nathan Fellman
-1 terrible hack. Join formatted pieces of strings, not other way around please
kaizer.se
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
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.
kaizer.se
adds an empty space at the end...
Shrikant Sharat
+1  A: 

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
Jed Smith
A generator expression would be even better: ", ".join("%.2f" % f for f in list_o_numbers)
efotinis
@efotinis Haven't added those to my repertoire yet, but you're right -- that's pretty sexy.
Jed Smith
Please do not edit my answer.
Jed Smith
@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
+8  A: 

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
+3  A: 

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

Echo
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)>>>a1.1000000000000001>>>b1.1000000000000001>>>print(a,b)1.1 1.1
Matt Boehm
A: 

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
While for loops aren't ugly, this usage isn't terribly Pythonic.
Jed Smith
+2  A: 
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
+1  A: 

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

voyager
+1  A: 

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)
kaizer.se
+3  A: 

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