0

Did my research and made several improvements, got very close to solving this issue but now I'm stuck and need help please.

Task: To convert a list of strings floats to floats with 2 decimal points

Original list:

mylist = ['17.21', '33.40', '24.39', '3.48', '1.02', '0.61', '18.03', '1.84']

Aim

mylist = [17.21, 33.40, 24.39, 3.48, 1.02, 0.61, 18.03, 1.84]

My script attempts

mylisttwo = map(float, mylist)

It gave me this

[17.21, 33.4, 24.39, 3.48, 1.02, 0.60999999999999999, 18.03, 1.84]

Then I thought id format it

floatlist = []
for item in mylisttwo:
    floatlist.append("{0:.2f}".format(item))

but that gave me a list of string floats again!! arghhhh

['17.21', '33.40', '24.39', '3.48', '1.02', '0.61', '18.03', '1.84']

What am I doing wrong here?

Thanks

Boosted_d16
  • 13,340
  • 35
  • 98
  • 158
  • 1
    If you want them as floats and you are planning to do calculations with them, I wouldn't bother rounding them to 2 decimal places until the time when you need to display them. – jcfollower Aug 09 '13 at 14:54
  • 1
    Why do you care? (Serious question.) Is `0.60999999999999999` good enough for your purposes? If not, why not? – Mark Dickinson Aug 09 '13 at 16:31

4 Answers4

5

[round(float(i), 2) for i in mylist]

This should work. Format is for inserting strings in other strings, as in "Hello, {}! What is your favourite {}?".format("Jim", "colour").

If you want to the numbers to only exist to 2 decimal places, you could use the decimal module.

rlms
  • 10,650
  • 8
  • 44
  • 61
  • The rounding isn't accurate because of the way float is represented in python: http://docs.python.org/2/library/functions.html#round, but you're answer appears to be more relevant than simply saying 'its impossible', as said here in a similar question: http://stackoverflow.com/questions/14540143/python-3-float-decimal-points-precision – foamroll Aug 09 '13 at 14:50
  • I see where I went wrong, thanks. But in the software I'm using it gives me this [17.21, 33.4, 24.39, 3.48, 1.02, 0.60999999999999999, 18.03, 1.84]. index 5 wasn't rounded to two decimal points for some reason. – Boosted_d16 Aug 09 '13 at 14:53
  • See the above comment, computers work in binary, so just as in base 10 we can't represent 1/3 as a decimal exactly - it's 0.33333333333... - computers without an infinite amount of memory can't store some floating point numbers accurately. – rlms Aug 09 '13 at 14:58
  • What about using the Decimal module? – Boosted_d16 Aug 09 '13 at 15:04
  • 1
    `round` is not helpful here: your `round(float(i), 2)` won't change a thing. `float("0.61")` *already* returns the closest representable float to `0.61`, and the result of the `round` call will again be the closest representable float to `0.61`. – Mark Dickinson Aug 09 '13 at 16:29
  • I presumed the questioner didn't know how many decimal places they would be to in the list, although I suppose that isn't necessarily true looking at the example list he gave. – rlms Aug 09 '13 at 17:02
1

You asked a question "What am I doing wrong here?". I think, what you are doing wrong is passing as an argument to:

floatlist.append()

this:

"{0:.2f}".format(item)

Format method of str class is simply returning formatted string, and you are expecting to get fixed two decimal points float. Float does not give such an option. user2387370 is right, you should use Decimal.

Community
  • 1
  • 1
Lukasz
  • 426
  • 2
  • 13
0

solution is similar with numpy:

import numpy as np

np.round( [float(i) for i in mylist], 2)

returns:

array([ 17.21, 33.4 , 24.39, 3.48, 1.02, 0.61, 18.03, 1.84])

Paul
  • 3,920
  • 31
  • 29
0

I wrote the following code that takes your original list and maps it to your "Aim":

from decimal import Decimal

def str_to_float_with_precision(item):
    precision = 2
    return float(Decimal(item, precision))

items = ['17.21', '33.40', '24.39', '3.48', '1.02', '0.61', '18.03', '1.84']
floated_items = map(str_to_float_with_precision, items)
print floated_items

The result:

[17.21, 33.4, 24.39, 3.48, 1.02, 0.61, 18.03, 1.84]
Mahshid Zeinaly
  • 3,590
  • 6
  • 25
  • 32