繁体   English   中英

检查集合列表中的元素重叠

[英]Check element overlaps in list of sets

我有一个集合列表,ss,想测试一个“测试”是否满足条件:

对于 ss 中的每个集合,“test”中的集合中必须有一个元素。

代码如下:

ss = [{"a"}, {"c", "d", "e"}, {"b", "g"}]

test1 = {'a', 'c', 'b'}
test2 = {'a', 'c'}

print('Test1: ')
def match(ss, test):
    for s in ss:
        overlap = not s.isdisjoint(test)
        if not overlap:
            return False

    return True

print(match(ss, test1)) // true
print(match(ss, test2))  // false

有什么漏洞,或者有更好的方法吗?

这对我来说看起来不错,因为查看代码可以很好地传达其含义。 我的建议是,你避免双重not ,但:

disjoint = s.isdisjoint(test)
if disjoint:
    return False

这可能会使逻辑更容易遵循。 一旦你有了它,你也可以摆脱那个变量,直接检查isdisjoint值:

if s.isdisjoint(test):
    return False

这就是我将其保留的地方,以保持逻辑易于遵循。

如果你真的想要,你可以把它缩短为一行:

def match(ss, test):
    return all(not s.isdisjoint(test) for s in ss)

至于性能或正确性,对于这些要求,您将无法比这更好:为了从集合列表中的每个集合中判断一个集合 ( test ) 的任何元素是否包含,您必须检查每一组。 所以这证明你对这些集合的循环是合理的。 当你在寻找两个集合的交集时,使用标准的集合操作将是你能得到的最好的结果。

如果您有更专业的需求,或者一些更长的测试系列,您可以从早期的测试结果中做出一些假设(例如,通过以某种方式对您的test集进行排序),那么可能会有一些进一步的优化,但如果我们只是使用match进行单个测试,那么我认为您已经进行了足够的优化,无需担心。

另一种选择可能是.intersection(another_set) 对于列表中的每个集合,您将询问test是否至少有一个共同元素。 使用理解列表将是:

def match(ss, test):
   return all(len(test.intersection(s)) > 0 for s in ss)

没有理解列表:

def match(ss, test):
   answers = []
   for s in ss:
      answers.append(len(test.intersection(s)) > 0)
   return all(answers)

print(match(ss, test1)) # True
print(match(ss, test2)) # False

您可以做一个简单的理解来确定匹配的元素,然后检查满足条件的集合列表是否与ss相同:

ss = [{"a"}, {"c", "d", "e"}, {"b", "g"}]

test1 = {'a', 'c', 'b'}
test2 = {'a', 'c'}

def match(ss, test):
    matching = [s for s in ss if any(i for i in s if i in test)]
    return matching == ss

match(ss, test1) -> True
match(ss, test2) -> False

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM