为什么Python十进制和不是可交换的(更改顺序时的结果不同)
我使用带字符串的十进制来避免典型问题 我有两个字典,它们有相同的键和值,但键的顺序不同这些字典的值之和应为零。然而,当我按一定的顺序求和时,它不是零 这些是我的字典和我为确保值相同而进行的比较:为什么Python十进制和不是可交换的(更改顺序时的结果不同),python,python-3.x,floating-point,decimal,precision,Python,Python 3.x,Floating Point,Decimal,Precision,我使用带字符串的十进制来避免典型问题 我有两个字典,它们有相同的键和值,但键的顺序不同这些字典的值之和应为零。然而,当我按一定的顺序求和时,它不是零 这些是我的字典和我为确保值相同而进行的比较: a={'key_a':十进制('0'), “键B”:十进制('-1002708'), “key_C”:十进制('3965.5752'), “key_D”:十进制('991393.8'), “key_E”:十进制('-991393.8'), “键F”:十进制('1173.30984201680676226
a={'key_a':十进制('0'),
“键B”:十进制('-1002708'),
“key_C”:十进制('3965.5752'),
“key_D”:十进制('991393.8'),
“key_E”:十进制('-991393.8'),
“键F”:十进制('1173.309842016806762268907563'),
“key_G”:十进制('-7348.6248'),
“key_H”:十进制('6175.31495798319327731092437'),
“key_I”:十进制('-741'),
“key_J”:十进制('0'),
“key_K”:十进制('4641'),
“key_”:十进制('-3900'),
“key_L”:十进制('1038000'),
“key_M”:十进制('0'),
“键”:十进制('0'),
“key_O”:十进制('0'),
“key_P”:十进制('-3965.5752'),
“key_Q”:十进制('0'),
“键”:十进制('0'),
“键”:十进制('-15570'),
“键”:十进制('-19722')}
b={'key_C':十进制('3965.5752'),
“key_D”:十进制('991393.8'),
“键B”:十进制('-1002708'),
“key_K”:十进制('4641'),
“key_”:十进制('-3900'),
“key_J”:十进制('0'),
“键A”:十进制('0'),
“key_G”:十进制('-7348.6248'),
“key_H”:十进制('6175.31495798319327731092437'),
“key_I”:十进制('-741'),
“键”:十进制('0'),
“键”:十进制('0'),
“键”:十进制('-19722'),
“key_P”:十进制('-3965.5752'),
“key_M”:十进制('0'),
“key_L”:十进制('1038000'),
“键F”:十进制('1173.309842016806762268907563'),
“key_O”:十进制('0'),
“key_Q”:十进制('0'),
“key_E”:十进制('-991393.8'),
“键”:十进制('-15570')}
打印(已排序(list(a.keys())==已排序(list(b.keys())))#“True”,使键相同
打印(len(a),len(b))#“21”长度相同
keys=已排序(列表(a.keys())
对于k in键:
断言a[k]==b[k]#从不引发异常,因此值相同
sum_d=lambda d:sum(d[key]表示d中的键)#对字典中的所有值求和的函数
问题出在这里:
print(sum_d(a)、sum_d(b))35;“4E-22 0E-21”即使值相同,但总和不是WTF
当事情变得更加奇怪时
我想确定这是因为顺序,所以我颠倒了顺序
a_new={key:a[key]表示b.keys()中的key
b_new={key:b[key]表示a.keys()中的key
打印(sum_d(a_new)、sum_d(b_new))#“0E-21 4E-22”由于顺序的原因而反转的值
所以我的问题是为什么…为什么python sum不是可交换的?在b
中有两个“key\u H”键
删除
b
中的行'key_H':Decimal('6175.31495798319327731092437'),
后,求和结果是相同的。一般来说,浮点算术是不可交换的。Decimal
类是浮点型的
十进制算术运算的默认精度为28位。您可以通过改变上下文来改变这一点。例如,使用以下代码将精度提高到40位:
import decimal
decimal.getcontext().prec = 40
如果要引发不精确算术的异常,可以显式配置该异常。您可以显式设置上下文,例如:
decimal.setcontext(decimal.Context(
traps=[decimal.Inexact],
))
非常感谢,在最初的日志中我有一些私人信息,我已经纠正了这个问题,问题仍然是一样的。这里是上面代码的链接