我需要验证一个列表是否是另一个列表的子集-布尔返回是我所寻求的。
在交叉路口后的小列表上测试相等性是最快的方法吗?考虑到需要比较的数据集的数量,性能是极其重要的。
在讨论的基础上补充进一步的事实:
对于许多测试,这两个列表是否都是相同的?其中一个是静态查找表。 需要是一个列表吗?它不是——静态查找表可以是任何性能最好的表。动态的是一个字典,我们从中提取键来执行静态查找。
在这种情况下,最佳解决方案是什么?
我需要验证一个列表是否是另一个列表的子集-布尔返回是我所寻求的。
在交叉路口后的小列表上测试相等性是最快的方法吗?考虑到需要比较的数据集的数量,性能是极其重要的。
在讨论的基础上补充进一步的事实:
对于许多测试,这两个列表是否都是相同的?其中一个是静态查找表。 需要是一个列表吗?它不是——静态查找表可以是任何性能最好的表。动态的是一个字典,我们从中提取键来执行静态查找。
在这种情况下,最佳解决方案是什么?
当前回答
>>> a = [1, 3, 5]
>>> b = [1, 3, 5, 8]
>>> c = [3, 5, 9]
>>> set(a) <= set(b)
True
>>> set(c) <= set(b)
False
>>> a = ['yes', 'no', 'hmm']
>>> b = ['yes', 'no', 'hmm', 'well']
>>> c = ['sorry', 'no', 'hmm']
>>>
>>> set(a) <= set(b)
True
>>> set(c) <= set(b)
False
其他回答
下面的代码检查一个给定的集合是否是另一个集合的“适当子集”
def is_proper_subset(set, superset):
return all(x in superset for x in set) and len(set)<len(superset)
在python 3.5中,您可以执行[*set()][index]来获取元素。它比其他方法要慢得多。
one = [1, 2, 3]
two = [9, 8, 5, 3, 2, 1]
result = set(x in two for x in one)
[*result][0] == True
或者只用len和set
len(set(a+b)) == len(set(a))
集合理论不适用于列表,因为重复使用集合理论会导致错误的答案。
例如:
a = [1, 3, 3, 3, 5]
b = [1, 3, 3, 4, 5]
set(b) > set(a)
没有任何意义。是的,它给出了一个错误的答案,但这是不正确的,因为集合理论只是比较:1,3,5与1,3,4,5。你必须包括所有副本。
相反,你必须计算每一项的出现次数,并使用大于等于来检查。这不是很昂贵,因为它不使用O(N²)操作,也不需要快速排序。
#!/usr/bin/env python
from collections import Counter
def containedInFirst(a, b):
a_count = Counter(a)
b_count = Counter(b)
for key in b_count:
if a_count.has_key(key) == False:
return False
if b_count[key] > a_count[key]:
return False
return True
a = [1, 3, 3, 3, 5]
b = [1, 3, 3, 4, 5]
print "b in a: ", containedInFirst(a, b)
a = [1, 3, 3, 3, 4, 4, 5]
b = [1, 3, 3, 4, 5]
print "b in a: ", containedInFirst(a, b)
然后运行这个,你会得到:
$ python contained.py
b in a: False
b in a: True
另一种解决方案是使用十字路口。
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)
假设项是可哈希的
>>> 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)个条目要遍历和检查。