简体   繁体   中英

Django/Python convert float during list comprehension

I have a Django Queryset object called data containing string keys and float values.

I want to convert all floats to 2 decimal places.

If I do this:

>>> param1_values = [d[param1] for d in data]
>>> param1_values[:5]
[26.1, 24.6, 26.2444444444444, 27.3103448275862, 26.7576923076923]

...which is fine but I need to float to two decimal places.

However, if I do this:

>>> param1_values = ["%.2f" % d['mean_air_temp'] for d in data]
>>> param1_values[:5]
['26.10', '24.60', '26.24', '27.31', '26.76']

The numbers are what I wanted but they are converted to strings! Why does this occur and how do I solve it?

Any help appreciated.

You can use the built-in round function:

param1_values = [round(d[param1], 2) for d in data]

Note: The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.68. This is not a bug: it's a result of the fact that most decimal fractions can't be represented exactly as a float. See Floating Point Arithmetic: Issues and Limitations for more information.

This seems to be accurate enough for your use case. If you need a more precise answer see Ignacio's response using Decimal.

Due to unavoidable inaccuracies in IEEE 754 floating point representation , it is impossible to solve this while keeping them floats.

>>> l = [26.1, 24.6, 26.2444444444444, 27.3103448275862, 26.7576923076923]
>>> [decimal.Decimal(x).quantize(decimal.Decimal('0.1')) for x in l]
[Decimal('26.1'), Decimal('24.6'), Decimal('26.2'), Decimal('27.3'), Decimal('26.8')]

The appropriate field to use in Django if you want to store these is DecimalField (unless you're using SQLite, but that's a whole other kettle of fish).

Do you really need the values rounded, or are you simply wanting to display two values after the decimal point when displaying the values in a template? If you are working on a display issue, use the 'floatformat' filter . Again, if this is what you're trying to accomplish, I believe that as you roll through the list you can use "listitem|floatformat:-2" to get the desired result. If, instead, you wish to store and use the rounded version in Python, you'll not have an easy time of it .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM