我想测试一个有序集是否是更大的有序集的子集。我使用了元组和itertools.combinations
:
def subset_test(a, b):
return a in itertools.combinations(b, len(a))
例如,
>>> subset_test((0, 1, 2), (0, 3, 1, 4, 2))
True
>>> subset_test((0, 1, 2), (0, 3, 2, 4, 1))
False
它有效,但在测试大元组时速度很慢。
答案 0 :(得分:12)
您可以简单地使用迭代器来跟踪B
中的位置>>> A = (0, 1, 2)
>>> B = (0, 3, 1, 4, 2)
>>> b_iter = iter(B)
>>> all(a in b_iter for a in A)
True
答案 1 :(得分:3)
这样做的简单方法
>>> a = (0, 1, 2)
>>> b = (0, 3, 1, 4, 2)
>>> filter(set(a).__contains__, b) == a
True
为提高效率,请使用itertools
>>> from itertools import ifilter, imap
>>> from operator import eq
>>> all(imap(eq, ifilter(set(a).__contains__, b), a))
True
答案 2 :(得分:1)
这应该让你入门
>>> A = (0, 1, 2)
>>> B = (0, 3, 1, 4, 2)
>>> b_idxs = {v:k for k,v in enumerate(B)}
>>> idxs = [b_idxs[i] for i in A]
>>> idxs == sorted(idxs)
True
如果列表推导会引发KeyError
,那么答案显然也是False
答案 3 :(得分:1)
这应该很快,但我想要更快,我希望很快就会失败:
def is_sorted_subset(A, B):
try:
subset = [B.index(a) for a in A]
return subset == sorted(subset)
except ValueError:
return False
更新:这是我承诺的更快。
def is_sorted_subset(A, B):
max_idx = -1
try:
for val in A:
idx = B[max_idx + 1:].index(val)
if max(idx, max_idx) == max_idx:
return False
max_idx = idx
except ValueError:
return False
return True
答案 4 :(得分:1)
这是一个线性时间方法(在最长的集合中),不需要任何散列。它利用了以下事实:由于两个集合都是有序的,因此不需要重新检查集合中的早期项目:
>>> def subset_test(a, b):
... b = iter(b)
... try:
... for i in a:
... j = b.next()
... while j != i:
... j = b.next()
... except StopIteration:
... return False
... return True
...
一些测试:
>>> subset_test((0, 1, 2), (0, 3, 1, 4, 2))
True
>>> subset_test((0, 2, 1), (0, 3, 1, 4, 2))
False
>>> subset_test((0, 1, 5), (0, 3, 1, 4, 2))
False
>>> subset_test((0, 1, 4), (0, 3, 1, 4, 2))
True
我很确定这是对的 - 如果你发现任何问题,请告诉我。
答案 5 :(得分:-1)
这个怎么样?
>>> a = (0, 1, 2)
>>> b = (0, 3, 1, 4, 2)
>>> set(a).issubset(set(b))
True
在此示例中,a和b具有有序和唯一元素,并检查a是否为b的子集。这是你想要的吗?
编辑:
据@Marcos da Silva Sampaio说:“我想测试A是否是有序集合B的子集。”
不会是这样的情况:
>>> a = (2, 0, 1)
>>> b = (0, 3, 1, 4, 2)
>>> set(b).issuperset(a)
True
在这种情况下,a的顺序无关紧要。