检查两个无序列表是否相等

我正在寻找一种简单(快速)的方法来确定两个无序列表是否包含相同的元素:

例如:

['one', 'two', 'three'] == ['one', 'two', 'three'] : true ['one', 'two', 'three'] == ['one', 'three', 'two'] : true ['one', 'two', 'three'] == ['one', 'two', 'three', 'three'] : false ['one', 'two', 'three'] == ['one', 'two', 'three', 'four'] : false ['one', 'two', 'three'] == ['one', 'two', 'four'] : false ['one', 'two', 'three'] == ['one'] : false 

我希望能够在不使用地图的情况下做到这一点。

Python有一个内置的数据types,用于无序集合(可哈希),称为set 。 如果将两个列表转换为集合,比较将是无序的。

 set(x) == set(y) 

set文件


编辑:@mdwhatcott指出,你想检查重复。 set忽略这些,所以你需要一个类似的数据结构,也跟踪每个列表中的项目数。 这就是所谓的multiset ; 标准库中最好的近似值是一个collections.Counter

 >>> import collections >>> compare = lambda x, y: collections.Counter(x) == collections.Counter(y) >>> >>> compare([1,2,3], [1,2,3,3]) False >>> compare([1,2,3], [1,2,3]) True >>> compare([1,2,3,3], [1,2,2,3]) False >>> 

如果元素总是按照你的例子进行sorting,那么内build的.sort() ( timsort )应该是快速的:

 >>> a = [1,1,2] >>> b = [1,2,2] >>> a.sort() >>> b.sort() >>> a == b False 

如果你不想sorting就可以使用sorted()

实际上,它可能总是比collections.Counter()快(尽pipe渐近地O(n)时间比O(n*log(n))更好。 测量它; 如果这很重要。

你想看看它们是否包含相同的元素,但不关心顺序。

你可以使用一个集合:

 >>> set(['one', 'two', 'three']) == set(['two', 'one', 'three']) True 

但是set对象本身只包含每个唯一值的一个实例,并且不会保存顺序。

 >>> set(['one', 'one', 'one']) == set(['one']) True 

所以,如果跟踪重复/长度是重要的,你可能也想检查长度:

 def are_eq(a, b): return set(a) == set(b) and len(a) == len(b) 
 sorted(x) == sorted(y) 

从这里复制: 检查两个无序列表是否相等

我认为这是这个问题的最佳答案,因为

  1. 正如在这个答案中所指出的,它比使用计数器更好
  2. x.sort()对x进行sorting,这是一个副作用。 sorting(x)返回一个新的列表。

如果你不想使用集合库,你总是可以做这样的事情:假设ab是你的列表,以下返回匹配元素的数量(它认为顺序)。

 sum([1 for i,j in zip(a,b) if i==j]) 

因此,

 len(a)==len(b) and len(a)==sum([1 for i,j in zip(a,b) if i==j]) 

如果两个列表相同,则包含相同的元素,并且顺序相同。 否则为False

因此,您可以像上面的第一个响应一样定义比较函数,但不包含集合库。

 compare = lambda a,b: len(a)==len(b) and len(a)==sum([1 for i,j in zip(a,b) if i==j]) 

 >>> compare([1,2,3], [1,2,3,3]) False >>> compare([1,2,3], [1,2,3]) True >>> compare([1,2,3], [1,2,4]) False 

对上述问题的一个class轮答案是:

让两个列表是list1和list2,而你的要求是确保两个列表是否具有相同的元素,那么按照我的意思,以下是最好的方法:

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

上面这段代码可以根据你的需要工作,即list1的所有元素是否在list2和副 – 诗。

但是如果你只想检查list1中的所有元素是否存在于list2中,那么你只需要使用下面的代码块: –

 if all(i in list2 for i in list1): print 'True' else: print 'False' 

不同之处在于,如果list2包含一些额外的元素以及list1的所有元素,则后者将打印为True。 简而言之,它将确保list1的所有元素都应该出现在list2中,而不pipelist2是否有一些额外的元素。

假设你已经知道列表的大小是相等的,那么当且仅当两个向量完全相同(包括顺序)

 functools.reduce(lambda b1,b2: b1 and b2, map(lambda e1,e2: e1==e2, listA, ListB), True) 

例:
>>>从functools导入减less
>>> def compvecs(a,b):
… return reduce(lambda b1,b2:b1和b2,map(lambda e1,e2:e1 == e2,a,b),True)

>>> compvecs(a = [1,2,3,4],b = [1,2,4,3])

>>> compvecs(a = [1,2,3,4],b = [1,2,3,4])
真正
>>> compvecs(a = [1,2,3,4],b = [1,2,4,3])

>>> compare_vectors(a = [1,2,3,4],b = [1,2,2,4])

>>>

如何获得列表的string表示并比较它们?

 >>> l1 = ['one', 'two', 'three'] >>> l2 = ['one', 'two', 'three'] >>> l3 = ['one', 'three', 'two'] >>> print str(l1) == str(l2) True >>> print str(l1) == str(l3) False