我需要验证一个列表是否是另一个列表的子集-布尔返回是我所寻求的。
在交叉路口后的小列表上测试相等性是最快的方法吗?考虑到需要比较的数据集的数量,性能是极其重要的。
在讨论的基础上补充进一步的事实:
对于许多测试,这两个列表是否都是相同的?其中一个是静态查找表。 需要是一个列表吗?它不是——静态查找表可以是任何性能最好的表。动态的是一个字典,我们从中提取键来执行静态查找。
在这种情况下,最佳解决方案是什么?
我需要验证一个列表是否是另一个列表的子集-布尔返回是我所寻求的。
在交叉路口后的小列表上测试相等性是最快的方法吗?考虑到需要比较的数据集的数量,性能是极其重要的。
在讨论的基础上补充进一步的事实:
对于许多测试,这两个列表是否都是相同的?其中一个是静态查找表。 需要是一个列表吗?它不是——静态查找表可以是任何性能最好的表。动态的是一个字典,我们从中提取键来执行静态查找。
在这种情况下,最佳解决方案是什么?
当前回答
如果我迟到了,请原谅。;)
为了检查集合A是否是集合B的子集,Python有a.is子集(B)和A <= B。它只对集合起作用,而且工作得很好,但内部实现的复杂性是未知的。参考:https://docs.python.org/2/library/sets.html #集对象
我提出了一种算法来检查列表A是否是列表B的子集。
To reduce complexity of finding subset, I find it appropriate to sort both lists first before comparing elements to qualify for subset. It helped me to break the loop when value of element of second list B[j] is greater than value of element of first list A[i]. last_index_j is used to start loop over list B where it last left off. It helps avoid starting comparisons from the start of list B (which is, as you might guess unnecessary, to start list B from index 0 in subsequent iterations.) Complexity will be O(n ln n) each for sorting both lists and O(n) for checking for subset. O(n ln n) + O(n ln n) + O(n) = O(n ln n). Code has lots of print statements to see what's going on at each iteration of the loop. These are meant for understanding only.
检查一个列表是否是另一个列表的子集
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
其他回答
如果你在问一个列表是否“包含”在另一个列表中,那么:
>>>if listA in listB: return True
如果你想知道listA中的每个元素在listB中是否有相等数量的匹配元素,试试:
all(True if listA.count(item) <= listB.count(item) else False for item in listA)
下面是我如何知道如果一个列表是另一个列表的子集,在我的情况下,序列对我很重要。
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
假设项是可哈希的
>>> 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)个条目要遍历和检查。
使用set.issubset
例子:
a = {1,2}
b = {1,2,3}
a.issubset(b) # True
a = {1,2,4}
b = {1,2,3}
a.issubset(b) # False
Python为此提供的性能函数是set. is子集。然而,它确实有一些限制,不清楚它是否能回答你的问题。
一个列表可以多次包含项目,并具有特定的顺序。而一组则不是。此外,set只适用于可哈希对象。
您是在询问子集还是子序列(这意味着您将需要字符串搜索算法)?对于许多测试,这两个列表是否都是相同的?列表中包含哪些数据类型?就此而言,它需要是一个列表吗?
你的另一篇文章交叉了字典和列表,使类型更清晰,并建议使用字典键视图来实现类似于集合的功能。在这种情况下,它是可以工作的,因为字典键的行为类似于集合(以至于在Python中有集合之前,我们使用字典)。人们不禁要问,为什么这个问题在三个小时内变得不那么具体了。
one = [1, 2, 3]
two = [9, 8, 5, 3, 2, 1]
set(x in two for x in one) == set([True])
如果list1在list 2中:
(x in two for x in one)生成一个True列表。 当我们做一个集合(x in two for x in one)只有一个元素(True)。