goodvibration
goodvibration

Reputation: 6206

Dictionary record is truncated when printing

I have a dictionary containing some floating-point values.

When I print the dictionary as is, I get these values printed in full accuracy.

However, when I attempt to print each value separately, I get them truncated.

A simple coding example to illustrate the problem:

d = {'x': 0.010000000000000231}
print d      # outputs {'x': 0.010000000000000231}
print d['x'] # outputs 0.01

Now, of course I can solve this using format, i.e., in the example above:

print '{:.18f}'.format(d['x']) # outputs 0.010000000000000231

However, I wish to avoid this kind of solution.

First and foremost, because I do not know the exact precision required for each entry in the dictionary. Second, because I prefer to avoid the type of cumbersome coding, which involves specifying print format of every field to begin with.

In other words, I want to do something like:

print 'x = {}'.format(d['x'])

Or:

print 'x =',d['x']

And get the value of d['x'] printed in its full precision.

Why does the Python interpreter chooses different print formats for d and for d['x'], and what approach can I take here in order to achieve my purpose?

Upvotes: 9

Views: 2764

Answers (2)

Stefan Pochmann
Stefan Pochmann

Reputation: 28596

When I print the dictionary as is, I get these values printed in full accuracy.

No, not really. Example (note the different last digit):

>>> d = {'x': 0.010000000000000232}
>>> print d
{'x': 0.010000000000000233}

And neither is the actual full accuracy of what d['x'] is:

>>> print ('%.2000f' % d['x']).rstrip('0')
0.01000000000000023266111259800936750252731144428253173828125

What you get when you print the dictionary is the repr string. What you get when you print just the float is the str string:

>>> print d['x']
0.01
>>> print str(d['x'])
0.01
>>> print repr(d['x'])
0.010000000000000233

So just use repr if you want the same output as in the printing of the dictionary.

I think the reason is that when you print a number, it's likely to be shown to an end user. And a value like 0.010000000000000231 in reality (i.e., not artificially entered like you did) is more likely the result of imprecision of a computer's calculation and the real value really is 0.01 instead. Like when you made calculations with prices in dollars, so 0.01 means 1 cent. So it makes more sense to show that to the end user instead of 0.010000000000000231.

But when you print a dictionary or other larger structure, that's likely not shown to an end user but more likely a developer wanting it as debug output. And for the developer, it's important to get a value that "accurately" represents the stored value, not a prettified version.

Upvotes: 1

cs95
cs95

Reputation: 402393

What you're seeing is a difference between what is printed when the __str__ method is invoked vs when the __repr__ is invoked.

An example:

In [816]: print 0.010000000000000231
0.01

In [817]: print repr(0.010000000000000231)
0.010000000000000231

The reason for this difference is because str attempts to truncate the number in python2.

This is changed in python3, and the str and repr behave consistently.

Upvotes: 3

Related Questions