有序子集测试

时间:2012-08-05 22:06:03

标签: python tuples subset itertools

我想测试一个有序集是否是更大的有序集的子集。我使用了元组和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

它有效,但在测试大元组时速度很慢。

6 个答案:

答案 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的顺序无关紧要。

相关问题