我正在寻找一种简单(快速)的方法来确定两个无序列表是否包含相同的元素:
例如:
['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有一个内置的数据类型,用于存储(可哈希)事物的无序集合,称为set
。如果将两个列表都转换为集合,则比较将无序。
set(x) == set(y)
编辑:@mdwhatcott指出您要检查重复项。set
忽略这些,因此您需要一个类似的数据结构,该结构还可以跟踪每个列表中的项目数。这称为多集;标准库中的最佳近似值为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
>>>
如果元素总是像您的示例中那样几乎被排序,则内建.sort()
(timsort)应该很快:
>>> a = [1,1,2]
>>> b = [1,2,2]
>>> a.sort()
>>> b.sort()
>>> a == b
False
如果您不想就地排序,可以使用sorted()
。
在实践中它可能永远是那么快collections.Counter()
(尽管渐进O(n)
时间是更好,然后O(n*log(n))
进行.sort()
)。测量它;如果重要的话。
sorted(x) == sorted(y)
从此处复制:检查两个无序列表是否相等
我认为这是此问题的最佳答案,因为
- 这比使用此答案中指出的计数器要好
- x.sort()对x进行排序,这是一个副作用。sorted(x)返回一个新列表。
您想查看它们是否包含相同的元素,但不在乎顺序。
您可以使用一组:
>>> 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)
如果您不想使用collections库,则始终可以执行以下操作:给定a
并且b
是您的列表,以下内容返回匹配元素的数量(它考虑顺序)。
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])
将是True
,如果两个列表是相同的,包含相同的元素,并以相同的顺序。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
对于上述问题的一个班轮答案是:
让两个列表分别为list1和list2,而您的要求是确保两个列表是否具有相同的元素,那么按照我的看法,以下将是最好的方法:
if ((len(list1) == len(list2)) and
(all(i in list2 for i in list1))):
print 'True'
else:
print 'False'
上面的代码将根据您的需要进行工作,即list1的所有元素是否在list2中,反之亦然。
但是,如果您只想检查list2中是否存在list1的所有元素,则只需要使用以下代码即可:-
if all(i in list2 for i in list1):
print 'True'
else:
print 'False'
区别在于,如果list2包含一些额外的元素以及list1的所有元素,则后者将打印True。简而言之,它将确保list1的所有元素都应存在于list2中,而不管list2是否具有一些额外的元素。
假设您已经知道列表大小相等,则以下情况将保证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
>>>
如何获取列表的字符串表示形式并进行比较?
>>> l1 = ['one', 'two', 'three']
>>> l2 = ['one', 'two', 'three']
>>> l3 = ['one', 'three', 'two']
>>> print str(l1) == str(l2)
True
>>> print str(l1) == str(l3)
False
文章标签:comparison , list , python
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!
评论已关闭!