1

我很难在字典中四舍五入。我所拥有的是这样的字典列表:

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}]

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

当我尝试以下操作时:

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 理解。首先,我很难遍历原始所有字典中的所有键和值。其次,这个结果在函数内部打印时只有 1 个小数点而不是 2 个小数点?第三,为什么“json.dumps”和“print”没有显示函数内部的值?

编辑:

使用下面的@Mark Ransom 的答案,我得到了所需的 o/p。但是,我必须对json.dumps值进行 urlencode 并将其发送到 URL。在 URL 处,它将值解码为所有小数位。因此,例如,如果josn.dumps给出 {"a": 9.1},则 URL 将其(在 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} 在 URL 之后给出urlencode9.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}]

在 URL 处,我得到如下值18.200000762939453(此值来自稍后的脚本运行)

4

7 回答 7

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}]'
于 2013-10-02T21:17:18.340 回答
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
于 2013-10-02T19:39:34.973 回答
2

JSONEncoder使用repr, 并repr以所有可用的精度打印浮点数。唯一可能的解决方案是在实际将值转换为字符串时继承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'
于 2013-10-02T20:21:14.383 回答
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
于 2013-10-02T19:27:43.817 回答
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}
于 2013-10-03T00:26:59.740 回答
1

我知道这个问题很老,但这是一个快速的单行解决方案,至少在 Linux Python 2.7.6 中有效,其他人可能会感兴趣:

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

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

于 2016-02-12T09:03:16.777 回答
0
[[round(d[key],2) for key in d] for d in y]
[{key:round(d[key], 2) for key in d} for d in y]
于 2021-09-17T11:16:38.923 回答