如何断言两个列表在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它们的顺序如何
这里是一个简单的例子,它比较两个具有相同元素但顺序不同的列表。
- 使用
assertCountEqual
testing会成功 - 使用
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代码上的代码