我认为这肯定已经得到了解答,但我在Google或此处找不到任何内容。
我知道,一般来说,你不能依赖Python字典的排序。但是,如果您有两个带有相同键的词典,那么您是否可以依赖相同顺序的值?
我问,因为我试图比较浮点数的两个字典,所以我不能使用dict1==dict2
。我的功能看起来像这样:
def _compare_dict(self, d1, d2):
"""
Compares two dictionaries of floating point numbers
for equality.
"""
if d1.keys() != d2.keys():
return False
zipped = zip(d1.itervalues(), d2.itervalues())
return len(filter(lambda x: abs(x[0] - x[1]) > sys.float_info.epsilon, zipped)) == 0
这是一场危险的比赛吗?在一次测试中,订单似乎成立:
In [126]: d1={'a': 3, 'b': 2, 'c': 10}
In [127]: d2={'b': 10, 'c': 7, 'a': 2}
In [128]: d1
Out[128]: {'a': 3, 'b': 2, 'c': 10}
In [129]: d2
Out[129]: {'a': 2, 'b': 10, 'c': 7}
但我不知道这是否值得我依赖。当然,其他用于比较两个浮点数字典的解决方案也是受欢迎的。
答案 0 :(得分:8)
根据词典的构建方式,你不能依赖它。
一些例子:
>>> a = dict.fromkeys(range(1000))
>>> b = dict.fromkeys(range(500,600))
>>> for i in range(500):
del a[i]
>>> for i in range(600,1000):
del a[i]
>>> all(i==j for i,j in zip(a,b))
False
>>> a == b
True
a
是一个更大的哈希表,因为它为1000个对象分配了空间,而b
只能容纳大约100个而不会增长一点。因此存储哈希的方式可以改变迭代顺序
答案 1 :(得分:3)
def _compare_dict(self, d1, d2):
"""
Compares two dictionaries of floating point numbers
for equality.
"""
if len(d1) != len(d2): # comparing `.keys()` is futile and slow
return False
try:
return all(abs(d1[k] - d2[k]) < sys.float_info.epsilon for k in d1)
except KeyError:
return False
对于小于-2
或大于2
的数字,此仍然无效,因为您错误地考虑了epsilon
相反,您需要选择一种方法来比较有意义的浮点数。您可以选择使用固定的epsilon,但这只会达到一定程度。花车可能非常大。
使用相对比较通常比绝对
更好答案 2 :(得分:2)
我建议这样的事情:
def _compare_dict(self, d1, d2):
if set(d1.keys()) != set(d2.keys()):
return False
for key in d1:
if abs(d1[key]-d2[key]) > sys.float_info.epsilon:
return False
return True
它易于阅读,只要注意到两个不在False
范围内的值而不是比较所有值,它就会返回sys.float_info.epsilon
。
答案 3 :(得分:1)
字典未订购,除非您使用python 3.3中存在的frozen dict,否则无法对它们进行排序
现在要比较键,您可以将键转换为一组:
a = {'a': 0, 'b': 1}
b = set(a)
c = set(a.keys()) # just another way to be clearer
b == c
True
或者你可以创建一个列表并命令它来比较它们,我更喜欢设置方法。