views:

64

answers:

4

Hi, I've some lists and more complex structures containing floats. When printing them, I see the floats with a lot of decimal digits, but when printing, I don't need all of them. So I would like to define a custom format (e.g. 2 or 3 decimals) when floats are printed.

I need to use floats and not Decimal. Also, I'm not allowed to truncate/round floats.

Is there a way to change the default behavior?

TIA ~Aki

+1  A: 

No, because that would require modifying float.__str__(), but you aren't allowed to monkeypatch C types. Use string interpolation or formatting instead.

Ignacio Vazquez-Abrams
Actually, it would require modifying `float.__repr__`. `str` only uses 12 significant digits.
dan04
A: 
>>> a = 0.1
>>> a
0.10000000000000001
>>> print a
0.1
>>> print "%0.3f" % a
0.100
>>>

From the Python docs, repr(a) would give 17 digits (as seen by just typing a at the interactive prompt, but str(a) (automatically performed when you print it) rounds to 12.

Edit: Most basic hack solution... You have to use your own class though, so...yeah.

>>> class myfloat(float):
...     def __str__(self):
...             return "%0.3f" % self.real
>>> b = myfloat(0.1)
>>> print repr(b)
0.10000000000000001
>>> print b
0.100
>>>
Nick T
+1  A: 

You are not aloud to monkeypatch C types, like Igacio said.

However, if you are terribly pressed in doing so and you know some C, you could go modify the Python interpreter source code yourself, then recompile it into a custom solution. Once I modified one of the standard behaviors for lists and it was only a moderate pain.

I suggest you find a better solution, such as just printing the floats with the "%0.2f" printf notation:

for item in mylist:
    print '%0.2f' % item,

or

print " ".join('%0.2f' % item for item in mylist)
orangeoctopus
The problem is that I've float inside lists, and when I print(list) I've no control on that. (This applies also for other objects, btw).Modifying source code is feasible as I know C, but isn't exactly what I was thinking of. Thanks.
AkiRoss
@AkiRoss: So then what you want to be fixing is the list, not the floats...
Ignacio Vazquez-Abrams
@AkiRoss, if you want more control just print the items individually.
orangeoctopus
@Ignacio, and what can I do if I've objects that use float.__str__ or float.__repr__ to str or repr themselves? What if I've nested lists with arbitrary length? I think that fixing these would be just wrong. Python provides __str__ and __repr__, and I think that the Right Way is to change them. I didn't know they were fixed for C types.
AkiRoss
Also, using a custom wrapper as Nick T suggested, would require to wrap all the computations, and I can't.
AkiRoss
If print uses str(obj) to convert the object to string, can't I override the default str() to return a custom string in case the parameter is a float and return the normal str() for the rest?I was reading PEP 3140
AkiRoss
A: 

Upgrade to Python 3.1. It doesn't use more digits than necessary.

Python 3.1.2 (r312:79147, Apr 15 2010, 15:35:48) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 0.1
0.1
dan04
Already using it. That's not the point, but thanks for the tip.
AkiRoss