floating point glitch

Michael Hoffman m.h.3.9.1.without.dots.at.cam.ac.uk at example.com
Sun Sep 26 04:38:04 EDT 2004


Tim Roberts wrote:

>>>>>a=[66.6, 333, 333, 1, 1234.5]
>>>>>print a.count(333), a.count(66.6), a.count('x')
>>
>>2 1 0
>>
>>>>>a.append(333)
>>>>>print a
>>
>>[66.599999999999994, 333, 333, 1, 1234.5, 333]
> 
> This is a FAQ.  The short answer is that 66.6 cannot be represented exactly
> in binary.  It is an infinitely repeating fraction.  (1234.5 is not, which
> is why the same thing didn't happen to it.)
> 
> When you use print, it calls repr() to get the string representation.

Actually, print essentialy uses str() to get the string representation. 
But repr(list) or str(list) still gets the repr() of each item of the 
list rather than the str():

 >>> class TestObject(object):
...     def __str__(self):
...         return "<str() called>"
...     def __repr__(self):
...         return "<repr() called>"
...
 >>> t = TestObject()
 >>> str(t)
'<str() called>'
 >>> repr(t)
'<repr() called>'
 >>> print t
<str() called>
 >>> t
<repr() called>
 >>> l = [TestObject()]
 >>> str(l)
'[<repr() called>]'
 >>> repr(l)
'[<repr() called>]'
 >>> print l
[<repr() called>]
 >>> l
[<repr() called>]

One way around this is to call str for each item yourself:

 >>> "[%s]" % ", ".join(map(str, l))
'[<str() called>]'

You could also define a list subclass that does this for you.
-- 
Michael Hoffman



More information about the Python-list mailing list