我知道,当对字典执行assertEqual
时,会调用assertDictEqual
。同样,序列上的assertEqual
将执行assertSequenceEqual
。
但是,当assertDictEqual
比较值时,似乎不使用assertEqual
,因此不调用assertSequenceEqual
。
请考虑以下简单字典:
lst1 = [1, 2]
lst2 = [2, 1]
d1 = {'key': lst1}
d2 = {'key': lst2}
self.assertEqual(lst1, lst2) # True
self.assertEqual(d1, d2) # False ><
如何通过递归地将类语义应用于值来测试字典,如
d1
和d2
以便正确比较它们的相等性?我希望尽可能避免使用外部模块(如建议的那样),除非它们是本机Django扩展。
编辑
本质上,我所追求的是一个内置版本:
def assertDictEqualUnorderedValues(self, d1, d2):
for k,v1 in d1.iteritems():
if k not in d2:
self.fail('Key %s missing in %s'%(k, d2))
v2 = d2[k]
if isinstance(v1, Collections.iterable) and not isinstance(v1, basestring):
self.assertValuesEqual(v1, v2)
else:
self.assertEqual(v1, v2)
上述代码的问题在于,错误消息不如内置断言那么好,而且可能存在我忽略的边缘情况(正如我刚在头上写下的那样)。
最佳答案
与其重写断言dictEqual,不如先对dict进行递归排序?
def deep_sort(obj):
"""
Recursively sort list or dict nested lists
"""
if isinstance(obj, dict):
_sorted = {}
for key in sorted(obj):
_sorted[key] = deep_sort(obj[key])
elif isinstance(obj, list):
new_list = []
for val in obj:
new_list.append(deep_sort(val))
_sorted = sorted(new_list)
else:
_sorted = obj
return _sorted
然后排序,并使用普通断言dicteequal:
dict1 = deep_sort(dict1)
dict2 = deep_sort(dict2)
self.assertDictEqual(dict1, dict2)
这种方法的好处是不关心你的列表有多深。
关于python - 如何通过将assertSequenceEqual应用于值来实现assertDictEqual,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18464095/