我需要验证一个列表是否是另一个列表的子集-布尔返回是我所寻求的。

在交叉路口后的小列表上测试相等性是最快的方法吗?考虑到需要比较的数据集的数量,性能是极其重要的。

在讨论的基础上补充进一步的事实:

对于许多测试,这两个列表是否都是相同的?其中一个是静态查找表。 需要是一个列表吗?它不是——静态查找表可以是任何性能最好的表。动态的是一个字典,我们从中提取键来执行静态查找。

在这种情况下,最佳解决方案是什么?


当前回答

如果你在问一个列表是否“包含”在另一个列表中,那么:

>>>if listA in listB: return True

如果你想知道listA中的每个元素在listB中是否有相等数量的匹配元素,试试:

all(True if listA.count(item) <= listB.count(item) else False for item in listA)

其他回答

假设项是可哈希的

>>> from collections import Counter
>>> not Counter([1, 2]) - Counter([1])
False
>>> not Counter([1, 2]) - Counter([1, 2])
True
>>> not Counter([1, 2, 2]) - Counter([1, 2])
False

如果你不关心重复的项目。[1,2, 2]和[1,2],然后使用:

>>> set([1, 2, 2]).issubset([1, 2])
True

在交叉路口后的小列表上测试相等性是最快的方法吗?

. is子集将是最快的方法。在测试子集之前检查长度不会提高速度,因为你仍然有O(N + M)个条目要遍历和检查。

另一种解决方案是使用十字路口。

one = [1, 2, 3]
two = [9, 8, 5, 3, 2, 1]

set(one).intersection(set(two)) == set(one)

集合的交点包含集合1

(OR)

one = [1, 2, 3]
two = [9, 8, 5, 3, 2, 1]

set(one) & (set(two)) == set(one)
one = [1, 2, 3]
two = [9, 8, 5, 3, 2, 1]

all(x in two for x in one)

解释:生成器通过遍历列表1检查该项是否在列表2中来创建布尔值。all()如果每一项都为真则返回True,否则返回False。

还有一个好处是,所有元素都在缺失元素的第一个实例上返回False,而不必处理每个元素。

由于没有人考虑比较两个字符串,下面是我的建议。

当然,您可能想检查管道(“|”)是否不属于这两个列表,可能会自动选择另一个char,但您已经明白了。

使用空字符串作为分隔符不是一个解决方案,因为数字可以有几个数字([12,3]!= [1,23])

def issublist(l1,l2):
    return '|'.join([str(i) for i in l1]) in '|'.join([str(i) for i in l2])

下面的代码检查一个给定的集合是否是另一个集合的“适当子集”

 def is_proper_subset(set, superset):
     return all(x in superset for x in set) and len(set)<len(superset)