首页 > 解决方案 > 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]不在最后一个列表中)。我所有的值都是唯一的,但不是ints ,而是dicts,这使得转换成一个集合很尴尬。

编辑:关于我想要比较的一些例子。它们是电话号码,由于不确定来自哪个国家/地区,因此有不同的解释:

[{'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'}]
}]

比较源部分不是问题,但不同的解释是。

解决这个问题的最佳方法是什么?

我想出了一些解决方案,但没有一个让人觉得很蟒蛇,而且可能效率低下:

有人有更好的主意吗?

标签: pythonpython-unittest

解决方案


我试图实现你所需要的。

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,因为它们是不可变的。


推荐阅读