在编写测试用例时,我经常需要断言两个列表包含相同的元素,而不考虑它们的顺序。
我一直在通过将列表转换为集合来做到这一点。
有没有更简单的方法来做到这一点?
编辑:
正如@MarkDickinson 指出的那样,我可以使用TestCase.assertItemsEqual。
TestCase.assertItemsEqual
Python2.7 中新增的注释。如果您使用的是旧版本的 Python,则可以使用unittest2 - Python 2.7 新功能的反向移植。
在编写测试用例时,我经常需要断言两个列表包含相同的元素,而不考虑它们的顺序。
我一直在通过将列表转换为集合来做到这一点。
有没有更简单的方法来做到这一点?
编辑:
正如@MarkDickinson 指出的那样,我可以使用TestCase.assertItemsEqual。
TestCase.assertItemsEqual
Python2.7 中新增的注释。如果您使用的是旧版本的 Python,则可以使用unittest2 - Python 2.7 新功能的反向移植。
从 Python 3.2 unittest.TestCase.assertItemsEqual
( doc ) 开始, (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()
旁注:请确保您要比较的列表中的元素是可排序的。
稍微快一点的实现版本(如果你知道大多数情侣列表会有不同的长度):
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
给定
l1 = [a,b]
l2 = [b,a]
assertCountEqual(l1, l2) # True
在 Python >= 2.7中,上述函数被命名为:
assertItemsEqual(l1, l2) # True
import unittest2
assertItemsEqual(l1, l2) # True
通过six
模块(任何 Python 版本)
import unittest
import six
class MyTest(unittest.TestCase):
def test(self):
six.assertCountEqual(self, self.l1, self.l2) # True
将列表转换为集合会告诉您它们包含相同的元素。但是这种方法不能确认它们包含相同数量的所有元素。例如,在这种情况下,您的方法将失败:
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
请注意,这不会改变两个列表的结构/内容。相反,排序创建了两个新列表
Needs ensure library but you can compare list by:
ensure([1, 2]).contains_only([2, 1])
This will not raise assert exception. Documentation of thin is really thin so i would recommend to look at ensure's codes on github