a = [1, 2, 3, 1, 2, 3]
b = [3, 2, 1, 3, 2, 1]
A和b应该被认为是相等的,因为它们有完全相同的元素,只是顺序不同。
问题是,我的实际列表将由对象(我的类实例)组成,而不是整数。
a = [1, 2, 3, 1, 2, 3]
b = [3, 2, 1, 3, 2, 1]
A和b应该被认为是相等的,因为它们有完全相同的元素,只是顺序不同。
问题是,我的实际列表将由对象(我的类实例)组成,而不是整数。
当前回答
from collections import defaultdict
def _list_eq(a: list, b: list) -> bool:
if len(a) != len(b):
return False
b_set = set(b)
a_map = defaultdict(lambda: 0)
b_map = defaultdict(lambda: 0)
for item1, item2 in zip(a, b):
if item1 not in b_set:
return False
a_map[item1] += 1
b_map[item2] += 1
return a_map == b_map
如果数据高度无序,排序可能会非常慢(当项具有某种程度的有序时,timsort特别好)。对两个列表进行排序也需要对两个列表进行完全迭代。
而不是改变列表,只是分配一个集合,并做左->右成员检查,保持每个项目存在的数量:
如果两个列表的长度不一样,可以立即短路并返回False。 如果你点击了列表a中任何不在列表b中的项,你可以返回False 如果查看了所有项,则可以比较a_map和b_map的值,以确定它们是否匹配。
在许多情况下,这允许您在迭代两个列表之前就短路。
其他回答
如果你知道项目总是可哈希的,你可以使用Counter(),它是O(n) 如果你知道这些项总是可排序的,你可以使用sorted()也就是O(n log n)
一般情况下,你不能依赖于排序能力,或者拥有元素,所以你需要一个像这样的后备方案,不幸的是,它是O(n²)
len(a)==len(b) and all(a.count(i)==b.count(i) for i in a)
如果要在测试上下文中执行比较,则使用assertCountEqual(a, b) (py>=3.2)和assertItemsEqual(a, b) (2.7<=py<3.2)。
也适用于不可哈希对象的序列。
from collections import defaultdict
def _list_eq(a: list, b: list) -> bool:
if len(a) != len(b):
return False
b_set = set(b)
a_map = defaultdict(lambda: 0)
b_map = defaultdict(lambda: 0)
for item1, item2 in zip(a, b):
if item1 not in b_set:
return False
a_map[item1] += 1
b_map[item2] += 1
return a_map == b_map
如果数据高度无序,排序可能会非常慢(当项具有某种程度的有序时,timsort特别好)。对两个列表进行排序也需要对两个列表进行完全迭代。
而不是改变列表,只是分配一个集合,并做左->右成员检查,保持每个项目存在的数量:
如果两个列表的长度不一样,可以立即短路并返回False。 如果你点击了列表a中任何不在列表b中的项,你可以返回False 如果查看了所有项,则可以比较a_map和b_map的值,以确定它们是否匹配。
在许多情况下,这允许您在迭代两个列表之前就短路。
如果你必须在测试中这样做: https://docs.python.org/3.5/library/unittest.html#unittest.TestCase.assertCountEqual
assertCountEqual(first, second, msg=None)
测试第一个序列是否包含与第二个序列相同的元素,而不管它们的顺序如何。当它们不这样做时,将生成一个错误消息,列出序列之间的差异。
在比较第一个和第二个元素时,不会忽略重复的元素。它验证两个序列中每个元素的计数是否相同。等价于:assertEqual(Counter(list(first)), Counter(list(second))),但也适用于不可哈希对象的序列。
3.2新版功能。
在2.7中: https://docs.python.org/2.7/library/unittest.html#unittest.TestCase.assertItemsEqual
在测试之外,我会推荐Counter方法。
如果列表中包含不可哈希的项(比如对象列表),你可以使用Counter类和id()函数,比如:
from collections import Counter
...
if Counter(map(id,a)) == Counter(map(id,b)):
print("Lists a and b contain the same objects")