如何断言两个列表在Python中包含相同的元素?

时间:2012-10-10 06:56:45

标签: python unit-testing

在编写测试用例时,我经常需要声明两个列表包含相同的元素而不考虑它们的顺序。

我一直在将列表转换为集合。

有没有更简单的方法呢?

修改

正如@MarkDickinson指出的那样,我可以使用TestCase.assertItemsEqual

注意TestCase.assertItemsEqual是Python2.7中的新功能。 如果您使用的是旧版本的Python,则可以使用unittest2 - Python 2.7新功能的后端。

5 个答案:

答案 0 :(得分:97)

从Python 3.2开始,unittest.TestCase.assertItemsEqualdoc)已被unittest.TestCase.assertCountEqualdoc)所取代,它正是您所寻找的,正如您可以从python standard library documentation。该方法有点误导性地命名,但它完全符合您的要求。

  

a和b具有相同数字的相同元素,无论其顺序如何

这是一个简单的例子,用于比较具有相同元素但顺序不同的两个列表。

  • 使用assertCountEqual测试将成功
  • 使用assertListEqual测试将因两个列表的顺序差异而失败

这是一个小例子脚本。

import unittest


class TestListElements(unittest.TestCase):
    def setUp(self):
        self.expected = ['foo', 'bar', 'baz']
        self.result = ['baz', 'foo', 'bar']

    def test_count_eq(self):
        """Will succeed"""
        self.assertCountEqual(self.result, self.expected)

    def test_list_eq(self):
        """Will fail"""
        self.assertListEqual(self.result, self.expected)

if __name__ == "__main__":
    unittest.main()

旁注:请确保您要比较的列表中的元素是可排序的。

答案 1 :(得分:43)

稍微快一点的实现版本(如果你知道大多数情侣列表会有不同的长度):

def checkEqual(L1, L2):
    return len(L1) == len(L2) and sorted(L1) == sorted(L2)

比较:

>>> timeit(lambda: sorting([1,2,3], [3,2,1]))
2.42745304107666
>>> timeit(lambda: lensorting([1,2,3], [3,2,1]))
2.5644469261169434 # speed down not much (for large lists the difference tends to 0)

>>> timeit(lambda: sorting([1,2,3], [3,2,1,0]))
2.4570400714874268
>>> timeit(lambda: lensorting([1,2,3], [3,2,1,0]))
0.9596951007843018 # speed up

答案 2 :(得分:22)

鉴于

l1 = [a,b]
l2 = [b,a]

In Python >= 3.0

assertCountEqual(l1, l2) # True

In Python >= 2.7,上面的函数命名为:

assertItemsEqual(l1, l2) # True

In Python < 2.7

import unittest2
assertItemsEqual(l1, l2) # True

答案 3 :(得分:19)

将列表转换为集合将告诉您它们包含相同的元素。但是这种方法无法确认它们包含相同数量的所有元素。例如,在这种情况下,您的方法将失败:

L1 = [1,2,2,3]
L2 = [1,2,3,3]

您可能最好对两个列表进行排序并进行比较:

def checkEqual(L1, L2):
    if sorted(L1) == sorted(L2):
        print "the two lists are the same"
        return True
    else:
        print "the two lists are not the same"
        return False

请注意,这不会改变两个列表的结构/内容。相反,排序会创建两个新列表

答案 4 :(得分:1)

需要确保库,但您可以按以下方式比较列表:

  

确保([1,2])。contains_only([2,1])

这不会引发断言异常。瘦文档很薄,所以我建议你看看ensure's codes on github