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

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

我一直在做这个通过转换列表设置。

有没有更简单的方法来做到这一点?

编辑

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

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

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

 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 

从Python 3.2开始, unittest.TestCase.assertItemsEqual已被unittest.TestCase.assertItemsEqual取代,您可以从python 标准库文档中读取它。 该方法有点误导性的命名,但它确实是你在找什么。

a和b具有相同数量的相同元素,而不pipe它们的顺序如何

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

  • 使用assertCountEqualtesting会成功
  • 使用assertListEqual ,由于两个列表的顺序不同,所以testing会失败

这里有一个小例子脚本。

 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 = [1,2,2,3] L2 = [1,2,3,3] 

你可能更好的sorting两个列表,并比较它们:

 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 

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

特定

 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 

需要确保图书馆,但你可以比较列表:

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

这不会引发exception。 薄的文档是非常薄,所以我build议看看保证G代码上的代码