我需要验证列表是否是另一个列表的一个子集 - 布尔返回是我所寻求的全部 在交叉路口之后,在最小的列表上测试相等性是最快的方法吗? 鉴于需要比较的数据集数量,性能至关重要 根据讨论添加更多事实:
根据情景,最佳解决方案是什么?
答案 0 :(得分:101)
Python为此提供的高性能函数是set.issubset。但它确实有一些限制,不清楚它是否是你问题的答案。
列表可能包含多次项目并具有特定订单。一套没有。要实现高性能集,只能处理hashable个对象。
您是在询问子集还是子序列(这意味着您需要字符串搜索算法)?对于许多测试,其中一个列表是否相同?列表中包含哪些数据类型?就此而言,它是否需要成为一个清单?
您的其他帖子intersect a dict and list使类型更清晰,并建议使用字典键视图来实现类似集合的功能。在那种情况下,它是有用的,因为字典键的行为就像一个集合(以至于在我们使用Python之前我们使用字典之前)。人们想知道这个问题在三小时内如何变得不那么具体。
答案 1 :(得分:101)
>>> 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
答案 2 :(得分:30)
do the decoding, rendering and encoding in the same thread
说明:生成器通过循环遍历列表one = [1, 2, 3]
two = [9, 8, 5, 3, 2, 1]
all(x in two for x in one)
来检查该项是否在列表one
中来创建布尔值。 Show + capture camera如果每个项目都是真实的,则返回two
,否则True
。
还有一个优点是False
在缺少元素的第一个实例上返回False,而不是必须处理每个项目。
答案 3 :(得分:20)
假设物品是可以清洗的
>>> 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
在交叉路口之后,在最小的列表上测试相等性是最快的方法吗?
.issubset
将是最快的方式。在测试issubset
之前检查长度不会提高速度,因为您仍然需要迭代并检查O(N + M)个项目。
答案 4 :(得分:5)
另一个解决方案是使用intersection
。
one = [1, 2, 3]
two = [9, 8, 5, 3, 2, 1]
set(one).intersection(set(two)) == set(one)
集合的交集将包含set one
(OR)
one = [1, 2, 3]
two = [9, 8, 5, 3, 2, 1]
set(one) & (set(two)) == set(one)
答案 5 :(得分:3)
我知道它已经很晚了,但只是想用适合我的方式更新答案 (Python 3)
# var 1
x = [1,2,3,4]
# var 2
y = [1,2]
# check if var2 is subset of var1
all([z in x for z in y])
干杯。
答案 6 :(得分:1)
由于没有人考虑过比较两个字符串,所以这是我的建议。
您当然想检查管道(“ |”)是否不在两个列表中,并可能自动选择另一个字符,但是您明白了。
使用空字符串作为分隔符不是解决方案,因为数字可以有几个数字([12,3]!= [1,23])
def issublist(l1,l2):
return '|'.join([str(i) for i in l1]) in '|'.join([str(i) for i in l2])
答案 7 :(得分:1)
集合理论不适合列表,因为重复使用集合理论会导致错误的答案。
例如:
SELECT p.Id ,
p.Name ,
p.ShortDescription ,
p.DisplayOrder ,
cat.Name AS CategoryName
FROM dbo.Product AS p
CROSS APPLY (
SELECT TOP 1
c.Name ,
c.Description ,
c.Id,
(CASE WHEN CONTAINS(cat.NAME, @search) THEN 1 ELSE 0 END) as IsCategoryMatching
FROM dbo.Product_Category_Mapping AS m
LEFT JOIN dbo.Category AS c ON m.CategoryId = c.Id
WHERE m.ProductId = p.Id
AND c.Published = 1
AND c.Deleted = 0
) AS cat
WHERE p.Published = 1
AND p.Deleted = 0
AND ( CONTAINS ( p.NAME, @search )
OR CONTAINS ( p.FullDescription, @search )
OR cat.IsCategoryMatching=1
);
没有意义。是的,它给出了错误的答案,但这是不正确的,因为集合论只是比较:1,3,5对1,3,4,5。您必须包含所有重复项。
相反,您必须计算每个项目的每个匹配项并执行大于等于检查的值。这不是很昂贵,因为它不使用O(N ^ 2)操作,也不需要快速排序。
a = [1, 3, 3, 3, 5]
b = [1, 3, 3, 4, 5]
set(b) > set(a)
然后运行这个你得到:
#!/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)
答案 8 :(得分:1)
one = [1, 2, 3]
two = [9, 8, 5, 3, 2, 1]
set(x in two for x in one) == set([True])
如果list1在列表2中:
(x in two for x in one)
生成True
列表。
当我们执行set(x in two for x in one)
时只有一个元素(True)。
答案 9 :(得分:1)
尝试按位AND
>>> set([1,2]) & set([1,2,3])
set([1, 2])
>>> set([0]) & set([1,2,3])
set([])
尚未对其进行分析。
答案 10 :(得分:0)
下面的代码检查给定的集合是否是另一个集合的“适当子集”
def is_proper_subset(set, superset):
return all(x in superset for x in set) and len(set)<len(superset)
答案 11 :(得分:0)
如果我迟到了,请原谅我。 ;)
要检查一个set A
是set B
的子集,Python
是A.issubset(B)
还是A <= B
。它仅适用于set
并且效果很好但内部实现的复杂性未知。参考:https://docs.python.org/2/library/sets.html#set-objects
我想出了一个算法来检查list A
是否是list B
的子集,并附有以下备注。
sort
首先列出
子集。break
的元素值大于第一个列表loop
的元素值时,它帮助我B[j]
A[i]
。last_index_j
用于启动loop
超过list B
的位置。它有助于避免从一开始就开始比较
list B
(正如您可能认为不必要的那样,在后续list B
中从index 0
开始iterations
。)复杂性将O(n ln n)
用于对两个列表进行排序,O(n)
用于检查子集。
O(n ln n) + O(n ln n) + O(n) = O(n ln n)
。
代码包含大量print
个语句,可以查看iteration
的每个loop
发生了什么。这些是为了理解
仅
检查一个列表是否是另一个列表的子集
is_subset = True;
A = [9, 3, 11, 1, 7, 2];
B = [11, 4, 6, 2, 15, 1, 9, 8, 5, 3];
print(A, B);
# skip checking if list A has elements more than list B
if len(A) > len(B):
is_subset = False;
else:
# complexity of sorting using quicksort or merge sort: O(n ln n)
# use best sorting algorithm available to minimize complexity
A.sort();
B.sort();
print(A, B);
# complexity: O(n^2)
# for a in A:
# if a not in B:
# is_subset = False;
# break;
# complexity: O(n)
is_found = False;
last_index_j = 0;
for i in range(len(A)):
for j in range(last_index_j, len(B)):
is_found = False;
print("i=" + str(i) + ", j=" + str(j) + ", " + str(A[i]) + "==" + str(B[j]) + "?");
if B[j] <= A[i]:
if A[i] == B[j]:
is_found = True;
last_index_j = j;
else:
is_found = False;
break;
if is_found:
print("Found: " + str(A[i]));
last_index_j = last_index_j + 1;
break;
else:
print("Not found: " + str(A[i]));
if is_found == False:
is_subset = False;
break;
print("subset") if is_subset else print("not subset");
<强>输出强>
[9, 3, 11, 1, 7, 2] [11, 4, 6, 2, 15, 1, 9, 8, 5, 3]
[1, 2, 3, 7, 9, 11] [1, 2, 3, 4, 5, 6, 8, 9, 11, 15]
i=0, j=0, 1==1?
Found: 1
i=1, j=1, 2==1?
Not found: 2
i=1, j=2, 2==2?
Found: 2
i=2, j=3, 3==3?
Found: 3
i=3, j=4, 7==4?
Not found: 7
i=3, j=5, 7==5?
Not found: 7
i=3, j=6, 7==6?
Not found: 7
i=3, j=7, 7==8?
not subset
答案 12 :(得分:0)
在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))
答案 13 :(得分:0)
在这里,我知道一个列表是否是另一个列表的子集,这对我而言很重要。
def is_subset(list_long,list_short):
short_length = len(list_short)
subset_list = []
for i in range(len(list_long)-short_length+1):
subset_list.append(list_long[i:i+short_length])
if list_short in subset_list:
return True
else: return False
答案 14 :(得分:0)
大多数解决方案都认为列表没有重复项。如果您的列表确实有重复,可以尝试以下操作:
def isSubList(subList,mlist):
uniqueElements=set(subList)
for e in uniqueElements:
if subList.count(e) > mlist.count(e):
return False
# It is sublist
return True
这可以确保子列表中的元素绝不会与列表中的元素不同,也不会包含更多的公共元素。
lst=[1,2,2,3,4]
sl1=[2,2,3]
sl2=[2,2,2]
sl3=[2,5]
print(isSubList(sl1,lst)) # True
print(isSubList(sl2,lst)) # False
print(isSubList(sl3,lst)) # False
答案 15 :(得分:-1)
如果您询问一个列表是否“包含”在另一个列表中,则:
>>>if listA in listB: return True
如果您询问listA中的每个元素是否在listB中具有相同数量的匹配元素,请尝试:
all(True if listA.count(item) <= listB.count(item) else False for item in listA)
答案 16 :(得分:-2)
如果a2 is subset of a1
,则Length of set(a1 + a2) == Length of set(a1)
a1 = [1, 2, 3, 4, 5];
a2 = [1, 2, 3];
len(set(a1)) == len(set(a1 + a2))