将dict值舍入为2位小数

时间:2013-10-02 19:19:59

标签: python dictionary rounding

我很难完成决定中的数值。我所拥有的是这样的词典列表:

y = [{'a': 80.0, 'b': 0.0786235, 'c': 10.0, 'd': 10.6742903}, {'a': 80.73246, 'b': 0.0, 'c':   
10.780323, 'd': 10.0}, {'a': 80.7239, 'b': 0.7823640, 'c': 10.0, 'd': 10.0}, {'a': 
80.7802313217234, 'b': 0.0, 'c': 10.0, 'd': 10.9762304}]

我需要将值四舍五入到小数点后两位。

当我尝试以下操作时:

def roundingVals_toTwoDeci(y):

    for d in y:
        for k, v in d.items():
            v = ceil(v*100)/100.0
            print v
            d[k] = v
    return
roundingVals_toTwoDeci(y)
s = json.dumps(y)
print s

我明白了:

0.0
0.0
18.2
0.0
27.3
54.5
0.0
0.0
0.0
[{"a": 0.0, "b": 0.0, "c": 27.300000000000001, "d": 0.0, "e": 54.5, "f": 0.0, "g": 18.199999999999999, "h": 0.0, "i": 0.0}]

我需要使用2.4+版本来完成这项工作,所以我没有使用dict理解。 首先,我很难在原始的所有dicts中循环遍历所有关键值。 第二,当它在函数内打印时,这个结果只有1个小数点而不是2个小数点? 第三,为什么'json.dumps'然后'print'没有显示函数内部的值?

编辑:

使用@Mark Ransom的答案,我得到了所需的o / p。但是,我必须对json.dumps值进行urlencode并将其发送到URL。在URL处,它将值解码为所有小数位。因此,例如,如果josn.dumps给出{“a”:9.1},则网址(在urlencode之后)显示为9.10034254344365。修改后的代码如下:

class LessPrecise(float):
    def __repr__(self):
        return str(self)

def roundingVals_toTwoDeci(y):
    for d in y:
        for k, v in d.items():
            v = LessPrecise(round(v, 2))
            print v
            d[k] = v




roundingVals_toTwoDeci(y)
j = json.dumps(y)
print j

params = urllib.urlencode({'thekey': j}) 

print json.dumps提供{"a": 9.1}urlencode之后的网址上,它会提供9.1078667322034而不是9.1,如下所示:

输出:::

100.0
0.0
0.0
0.0
100.0
0.0
0.0
0.0
81.8
0.0
18.2
0.0
90.0
0.0
0.0
10.0
[{"a": 100.0, "b": 0.0, "c": 0.0, "d": 0.0}, {"a": 100.0, "b": 0.0, "c": 0.0, "d": 0.0}, {"a":
81.8,  "b": 0.0, "c": 18.2, "d": 0.0}, {"a": 90.0, "b": 0.0, "c": 0.0, "d": 10.0}]

在网址:

9.100000381469727

json.dumps()

之后的JSON字符串
[{"a": 80.0, "b": 0.0, "c": 10.0, "d": 10.0}, {"a": 100.0, "b": 0.0, "c": 0.0, "d": 0.0}, {"a":  
80.0, "b": 0.0, "c": 10.0, "d": 10.0}, {"a": 90.0, "b": 0.0, "c": 0.0, "d": 10.0}]

urlencode字符串 - 在http://meyerweb.com/eric/tools/dencoder/解码后

thekey=[{"a": 80.0, "b": 0.0, "c": 10.0, "d": 10.0}, {"a": 100.0, "b": 0.0, "c": 0.0, "d": 
0.0}, {"a": 80.0, "b": 0.0, "c": 10.0, "d": 10.0}, {"a": 90.0, "b": 0.0, "c": 0.0, "d": 10.0}]

在网址上,我获得了18.200000762939453之类的值(此值来自以后的脚本运行)

6 个答案:

答案 0 :(得分:4)

从其他几个答案中获取最佳位:

class LessPrecise(float):
    def __repr__(self):
        return str(self)

def roundingVals_toTwoDeci(y):
    for d in y:
        for k, v in d.items():
            v = LessPrecise(round(v, 2))
            print v
            d[k] = v

>>> roundingVals_toTwoDeci(y)
80.0
10.0
0.08
10.67
80.73
10.78
0.0
10.0
80.72
10.0
0.78
10.0
80.78
10.0
0.0
10.98
>>> s=json.dumps(y)
>>> s
'[{"a": 80.0, "c": 10.0, "b": 0.08, "d": 10.67}, {"a": 80.73, "c": 10.78, "b": 0.0, "d": 10.0}, {"a": 80.72, "c": 10.0, "b": 0.78, "d": 10.0}, {"a": 80.78, "c": 10.0, "b": 0.0, "d": 10.98}]'

答案 1 :(得分:2)

import json


y = [{'a': 80.0, 'b': 0.0786235, 'c': 10.0, 'd': 10.6742903}, {'a': 80.73246, 'b': 0.0, 'c':   
10.780323, 'd': 10.0}, {'a': 80.7239, 'b': 0.7823640, 'c': 10.0, 'd': 10.0}, {'a': 
80.7802313217234, 'b': 0.0, 'c': 10.0, 'd': 10.9762304}]

def roundingVals_toTwoDeci(y):

    for d in y:
        for k, v in d.items():
            v = round(v,2) # <--- round() does exact that.
            d[k] = v # <--- You need to put the rounded v back in d
            print v
    return

roundingVals_toTwoDeci(y)
s = json.dumps(y)
print s

答案 2 :(得分:2)

JSONEncoder使用reprrepr打印具有所有可用精度的浮点数。唯一可能的解决方案是从JSONEncoder继承并实际将值转换为字符串(这意味着要复制和调整json.encoder模块中的某些代码),或者将浮点数包装到您自己的中键入RoundedFloat并为其注册序列化程序。另请注意,repr的行为取决于所使用的Python版本。

与非显而易见的行为一样,调试期间的观察可能会欺骗您:print在某一点使用str()str()轮,与repr()不同显示浮点数学的裸露丑陋。

证据在代码中:

>>> class F(float):
...     def __str__(self): return "str"
...     def __repr__(self): return "repr"
...     
... 
>>> print F(1)
str
>>> F(1)
repr
>>> repr(1-1e-15)
'0.999999999999999'
>>> str(1-1e-15)
'1.0'

答案 3 :(得分:1)

回答问题的第二部分

尝试使用以下代码替换代码的第5行:

 v = round(v, 2)

这会将数字四舍五入到小数点后两位。使用round,我得到了

[{'a': 80.0, 'c': 10.0, 'b': 0.08, 'd': 10.67}, {'a': 80.73, 'c': 10.78, 'b': 0.0, 'd': 10.0}, {'a': 80.72, 'c': 10.0, 'b': 0.78, 'd': 10.0}, {'a': 80.78, 'c': 10.0, 'b': 0.0, 'd': 10.98}]

我正在使用Python 2.7.2。这是所有代码:

from math import ceil 
import json

y = [{'a': 80.0, 'b': 0.0786235, 'c': 10.0, 'd': 10.6742903},
     {'a': 80.73246, 'b': 0.0, 'c': 10.780323, 'd': 10.0},
     {'a': 80.7239, 'b': 0.7823640, 'c': 10.0, 'd': 10.0},
     {'a': 80.7802313217234, 'b': 0.0, 'c': 10.0, 'd': 10.9762304}]

def roundingVals_toTwoDeci(y):
    for d in y:
        for k, v in d.items():
            v = round(v, 2)
            #print v
            d[k] = v
    return

roundingVals_toTwoDeci(y)
s = json.dumps(y)
print s

答案 4 :(得分:1)

我不明白与json有什么关系,但我可以提议:

from math import ceil

y = [{'a': 80.0, 'b': 0.0786235, 'c': 10.0, 'd': 10.6742903},
     {'a': 80.73246, 'b': 0.0, 'c': 10.780323, 'd': 10.0},
     {'a': 80.7239, 'b': 0.7823640, 'c': 10.0, 'd': 10.0},
     {'a': 80.7802313217234, 'b': 0.0, 'c': 10.0, 'd': 10.9762304}]

class TwoDec(float):
    def __repr__(self):
        return "%.2f" % self

def roundingVals_to_TwoDeci(y,ceil=ceil,TwoDec=TwoDec):
    for d in y:
        for k, v in d.iteritems():
            d[k] = TwoDec(ceil(v*100)/100)

roundingVals_to_TwoDeci(y)
for el in y:
    print el

结果

{'a': 80.00, 'c': 10.00, 'b': 0.08, 'd': 10.68}
{'a': 80.74, 'c': 10.79, 'b': 0.00, 'd': 10.00}
{'a': 80.73, 'c': 10.00, 'b': 0.79, 'd': 10.00}
{'a': 80.79, 'c': 10.00, 'b': 0.00, 'd': 10.98}

答案 5 :(得分:1)

我知道这个问题已经过时了,但这里有一个快速的单行解决方案,至少在Linux Python 2.7.6中有用,可能对其他人有用:

y = [{ x : round(z, 2) for x,z in yi.items()} for yi in y ]

但是,对于较大的数据集,这可能效率低下,因为它会重新生成列表/字典结构。