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

我一直通过将列表转换为集合来做到这一点。

有没有更简单的方法?

编辑:

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

注意到TestCase。assertItemsEqual是Python2.7中的新功能。 如果您使用的是较旧版本的Python,则可以使用unittest2—Python 2.7新特性的后备端口。


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

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

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


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

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

需要确保库,但你可以比较列表:

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

这将不会引发断言异常。薄的文档真的很薄,所以我建议看看确保在github上的代码


从Python 3.2开始,unittest.TestCase.assertItemsEqual(doc)已经被unittest.TestCase.assertCountEqual(doc)所取代,它所做的正是您所寻找的,正如您可以从Python标准库文档中阅读的那样。该方法的名称有些误导,但它确实是您正在寻找的。

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()

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


鉴于

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

在Python中>= 3.0

assertCountEqual(l1, l2) # True

在Python >= 2.7中,上述函数被命名为:

assertItemsEqual(l1, l2) # True

在Python中< 2.7

import unittest2
assertItemsEqual(l1, l2) # True

通过六个模块(任何Python版本)

import unittest
import six
class MyTest(unittest.TestCase):
    def test(self):
        six.assertCountEqual(self, self.l1, self.l2) # True