python - Unittest - 比较没有顺序的列表列表
问题描述
我的问题类似于unittest - compare list 不考虑 order,但略有不同:
我有一个返回列表列表的函数,没有任何保证顺序(对于两个级别)。我将它的输出与某个预定值“这应该是答案”进行比较来测试它。因此,如果should_be_the_answer == [[1,2], [3,4]]
,它应该传递以下回报:
[[1,2], [3,4]]
- [[3,4], [1,2]]
- [[2,1], [4,3]]
- [[3,4], [2,1]]
(以及更多变体)
但不是在混合时,所以[[1,3], [2,4]]
应该失败。
assertCountEqual
不起作用,因为它会比较子列表(比较第一个和最后一个会告诉我[1,2]
不在最后一个列表中)。我所有的值都是唯一的,但不是int
s ,而是dict
s,这使得转换成一个集合很尴尬。
编辑:关于我想要比较的一些例子。它们是电话号码,由于不确定来自哪个国家/地区,因此有不同的解释:
[{'source': '001123456789',
'interpretations': [
{'prefix': '00',
'country_code': '1',
'national_part': '123456789'},
{'prefix': '0011',
'country_code': '234',
'national_part': '56789'}]
}, {'source': '0011987654321',
'interpretations': [
{'prefix': '00',
'country_code': '1',
'national_part': '1987654321'},
{'prefix': '0011',
'country_code': '98',
'national_part': '7654321'}]
}]
比较源部分不是问题,但不同的解释是。
解决这个问题的最佳方法是什么?
我想出了一些解决方案,但没有一个让人觉得很蟒蛇,而且可能效率低下:
- 将子列表转换为集合,使用
repr
dicts 使之成为可能。但是将它们变成字符串只是为了比较它们感觉是错误的。如果 dict 的顺序发生变化,可能会导致错误。 - 对列表和/或子列表进行排序。这意味着为字典提供排序/比较功能,这可能是矫枉过正。
- 循环遍历子列表。对于每个值,尝试是否存在满足的相应子列表
assertCountEqual
。可以,但是当输出变大时,这有可能变得非常昂贵(尽管它可能适用于我的用例)
有人有更好的主意吗?
解决方案
我试图实现你所需要的。
tl; dr:repr()
您可以将它们转换为frozensets,而不是您的dicts
expected1 = [[1, 2], [3, 4]]
data1 = [[2, 1], [4, 3]]
def unorder(data, is_dict=False):
if is_dict:
return set(frozenset(frozenset(d.items()) for d in sublist) for sublist in data) # d is dict here
else:
return set(frozenset(sublist) for sublist in data)
assert unorder(data1) == unorder(expected1)
d1 = {'a': 1}
d2 = {'b': 2, 'x': 12}
d3 = {'c': 3}
d4 = {'d': 4, 'y': -23}
expected2 = [[d1, d2], [d3, d4]]
data2 = [[d2, d1], [d4, d3]]
assert unorder(data2, is_dict=True) == unorder(expected2, is_dict=True)
我使用frozensets 是因为您可以将frozenset 添加到另一个set,因为它们是不可变的。
推荐阅读
- java - 是否可以在不使用多个 catch 语句的情况下捕获多个异常并对它们执行不同的逻辑?
- matlab - 大向量的层次聚类
- python - 如何解决 TypeError:无法将系列转换为
- elixir - 创建发布版本后无法在 Elixir 中运行发布应用程序
- java - 使用 Spring Data JPA 初始化存储库
- vba - 将 Iferror 函数添加到 VBA
- reactjs - 有没有办法在反应原生中使用反应服务器发送的事件组件
- ios - 无法下载 gzip 文件的 bin 文件
- web-services - 如何在 Amadeus Web 服务中创建会话 ID 和安全令牌
- java - 在我的手机上使用 android studio 时,创建帐户不适用于 firebase