我试图解决这个问题有一段时间了,尝试在互联网上搜索并引用一些书籍,但还没有找到解决方案。
这里提出了一种解决方案,但不确定是否还有其他更简单的方法。
引用:Comparing Python dicts with floating point values included
希望你能给一些指点。
背景:
有一个带有 {key:{key:{key:[value]}}} 关系的 dict_A。这个 dict_A 将经过一个迭代过程,根据几个约束和一个优化目标来优化它的值。只有当最终优化的dict即dict_B2等于dict优化的一个周期之前,即dict_B1时,才会停止优化过程。这给人的印象是 dict 无法进一步优化,这用于打破迭代循环。
问题:
由于 dicts 值包含浮点数,因此某些存储的值会发生变化,这可能是因为字典以二进制格式存储值。请引用下面的示例,字典中第一个浮点值的变化。
dict_B1 = {0: {36: {3: [-1], 12: [0.074506333542951425]}}, 1: {36: {2: [-1], 16: [0.048116666666666676], 17: [-1]}}, 2: {}, 3: {36: {5: [-1], 6: [-1], 15: [0.061150932060349471]}}}
dict_B2 = {0: {36: {3: [-1], 12: [0.074506333542951439]}}, 1: {36: {2: [-1], 16: [0.048116666666666676], 17: [-1]}}, 2: {}, 3: {36: {5: [-1], 6: [-1], 15: [0.061150932060349471]}}}
如果我使用下面的,交互过程会无限循环并且不会中断,
if (dict_B1==dict_B2):
Exit
或者,
if (cmp(dict_B1,dict_B2)):
Exit
有没有其他方法可以比较字典,比如说,与 18 个浮点精度值中的 15 个浮点精度进行比较?
我尝试在字典中存储较低精度的浮点数。问题仍然存在。
希望你能帮助我指出正确的方向。
更新 1:Jakub 的建议
Jakub 的建议很好。我可以创建两个中间列表,即 List_B1 和 List_B2 来存储浮点数,它们将用于比较并作为决定何时中断迭代过程的标志。
下面是用于测试案例的代码。 List_B2 中的第二项被故意更改,因此该值远高于精度阈值。
def is_equal(floats_a, floats_b, precision=1e-15):
return all((abs(a-b) < precision) for a, b in izip(floats_a, floats_b))
List_B1=[0.074506333542951425,0.048116666666666676,0.061150932060349471]
List_B2=[0.074506333542951439,9.048116666666666676,0.061150932060349471]
print "is_equal(List_B1,List_B2):",is_equal(List_B1,List_B2)
for a, b in izip(List_B1, List_B2):
print a,b, (abs(a-b) < 1e-15)
结果:
is_equal(List_B1,List_B2): True
0.074506333543 0.074506333543 True
0.0481166666667 9.04811666667 False
0.0611509320603 0.0611509320603 True
奇怪的是
is_equal
函数总是返回不正确的 TRUE
,但是当剖析代码时,它可以正常工作。也许 return all
正在执行 OR
而不是 AND
。还在解决这个问题。如果您有任何提示,请分享。将继续努力解决这个问题。感谢 Jakub 和 Julien 到目前为止的所有指导。
rgds
沙拉湾
最佳答案
比较浮点数时,请始终牢记浮点数不是无限精度和累积误差。你真正感兴趣的是两个浮点数是否足够接近,而不是它们是否相等
如果你想测试两个浮点数列表是否相等,我会做
def is_equal(floats_a, floats_b, precision=1e-15):
return all((abs(a-b) < precision) for a, b in izip(floats_a, floats_b))
关于python - 比较两个字典 - 浮点数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16265800/