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

例如:

['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

我希望不用地图就能做到。


当前回答

如果元素总是像你的例子中那样几乎排序,那么内置的.sort() (timsort)应该很快:

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

如果你不想在某个位置排序,你可以使用sorted()。

在实践中,它可能总是比collections.Counter()更快(尽管对于.sort(),渐进地O(n)时间比O(n*log(n))时间更好)。测量;如果这很重要的话。

其他回答

获取列表的字符串表示形式并比较它们怎么样?

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

对上述问题的一个简单回答是:-

设两个列表为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中,而不管list2是否有一些额外的元素。

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

set(x) == set(y)

片场文件


编辑:@mdwhatcott指出你想检查重复。Set忽略了这些,所以您需要一个类似的数据结构来跟踪每个列表中的项的数量。这叫做多重集;标准库中最好的近似是集合。计数器:

>>> 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
>>> 

假设您已经知道列表的大小相等,当且仅当两个向量完全相同(包括顺序)时,下面的语句将保证为True

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

例子:

>>> from functools import reduce
>>> def compvecs(a,b):
...     return reduce(lambda b1,b2: b1 and b2, map(lambda e1,e2: e1==e2, a, b), True)
... 
>>> compvecs(a=[1,2,3,4], b=[1,2,4,3])
False
>>> compvecs(a=[1,2,3,4], b=[1,2,3,4])
True
>>> compvecs(a=[1,2,3,4], b=[1,2,4,3])
False
>>> compare_vectors(a=[1,2,3,4], b=[1,2,2,4])
False
>>> 

您希望查看它们是否包含相同的元素,但不关心顺序。

你可以使用一个集合:

>>> 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)