我正在编写Pytest,有两个函数返回两个列表。如何在Python 3.7中使用assert并比较两个无序列表?我想比较预期列表中存在的每个元素(子网(,并最好使用表驱动的测试
expected_list= ['subnet-123', 'subnet-456', 'subnet-789', 'subnet-000']
second_list= ['subnet-789', 'subnet-123', 'subnet-456', 'subnet-000']
def test_subnet_exist():
expected_list = get_expected_list()
second_list = get(second_list)
for expected_list in second_list:
assert second_list, "Subnet {} not found".format(subnet)
由于列表的顺序,它会导致"AssertionError"。使用assert排序是一种方法,但我很想知道是否可以检查second_list的每个元素是否存在于expected_list 中
旁注:get_expected_list()
和get(second_list)
是一种奇怪的选择,不会像写的那样出现在问题中。
如果你的元素不可散列、可排序,或者除了定义了相等之外没有其他方法,那么IIRC你不能比O(n^2)
做得更好,所以我假设它是可散列的(对于定义了相等的大多数合理对象,如果需要,你也可以子类化并定义自定义__hash__(self)
方法(。
只要你的元素是可散列的,你就可以依靠内置函数来测试成员资格。
def test_subnet_exists():
assert set(get_expected_list()).issubset(get(second_list))
如果出于任何原因需要循环(例如,详细记录哪些元素丢失(,那么您可能仍然希望使用集合来提高流程效率。
def test_subnet_exists():
# if hashability is impossible, leave this as `outer = get(second_list)`
# and accept the O(n^2) performance impact
outer = set(get(second_list))
for item in get_expected_list():
assert item in outer
由于您必须循环列表,并且我们知道它们不是唯一的(123出现两次,789在一秒内出现两次(,因此您可以对它们进行迭代,对吧?
顺便说一句,"预期列表"似乎是关键,而你希望确保第二个列表中的值都出现在"预期列表中",而不是相反。
expected_list= ['subnet-123', 'subnet-456', 'subnet-789', 'subnet-123', 'subnet-wrong']
second_list= ['subnet-789', 'subnet-123', 'subnet-456', 'subnet-789']
def test_subnet_exist():
expected = expected_list
second = second_list
for element in expected:
assert element in second, f"{element} not found"
print ("All elements found")
test_subnet_exist()
>>>AssertionError: subnet-wrong not found