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的值,以确定它们是否匹配。

在许多情况下,这允许您在迭代两个列表之前就短路。

其他回答

您可以编写自己的函数来比较这些列表。

让我们得到两个列表。

list_1=['John', 'Doe'] 
list_2=['Doe','Joe']

首先,我们定义一个空字典,计数列表项并写入字典。

def count_list(list_items):
    empty_dict={}
    for list_item in list_items:
        list_item=list_item.strip()
        if list_item not in empty_dict:
            empty_dict[list_item]=1
        else:
            empty_dict[list_item]+=1
    return empty_dict


        

之后,我们将使用下面的函数比较两个列表。

def compare_list(list_1, list_2):
    if count_list(list_1)==count_list(list_2):
        return True
    return False
compare_list(list_1,list_2)

代入这个:

def lists_equal(l1: list, l2: list) -> bool:
    """

    import collections
    compare = lambda x, y: collections.Counter(x) == collections.Counter(y)
    ref:
        - https://stackoverflow.com/questions/9623114/check-if-two-unordered-lists-are-equal
        - https://stackoverflow.com/questions/7828867/how-to-efficiently-compare-two-unordered-lists-not-sets
    """
    compare = lambda x, y: collections.Counter(x) == collections.Counter(y)
    set_comp = set(l1) == set(l2)  # removes duplicates, so returns true when not sometimes :(
    multiset_comp = compare(l1, l2)  # approximates multiset
    return set_comp and multiset_comp  #set_comp is gere in case the compare function doesn't work

我希望下面的代码可能在你的情况下工作:-

if ((len(a) == len(b)) and
   (all(i in a for i in b))):
    print 'True'
else:
    print 'False'

这将确保两个列表a和b中的所有元素都是相同的,无论它们的顺序是否相同。

为了更好的理解,请参考我对这个问题的回答

如果你必须在测试中这样做: 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")