【问题标题】:Find out if any two sets have the same membership找出任何两个集合是否具有相同的成员资格
【发布时间】:2020-05-13 12:04:19
【问题描述】:

我有六个集合,命名为 s1 ... s6,每个集合有几百个字符串元素。

我想测试一下它们中的任何一个是否与其他任何一个具有相同的元素集。我该如何设置?

为了它的价值,我从这个开始,试图打印一个罪犯的索引:

setlist = [s1, s2, s3, s4, s5, s6]

for i in range(len(setlist)):
    if any([setlist[i] == st for st in setlist[i+1:]]):
        print('You have redundant sets: %i' % i)

为了澄清,s1 - s6 都是 set() 类型。我需要能够查看哪些匹配,例如,如果 s2 和 s3 恰好有相同的成员,我希望看到 'You have redundant sets: s2, s3' 显然,我的起始代码不会让我到达那里。

【问题讨论】:

  • 您需要知道罪犯还是只知道有没有?
  • 请添加示例输入+输出。
  • 也许使用内置的set 类型会是你想要的? An example.

标签: python python-3.x set


【解决方案1】:
    s1={1,2,3}
    s2={2,3,4}
    s3={1,2,3}
    s4={1,2,3}
    s5={2,6,7}
    setlist = [s1, s2, s3, s4,s5]
    redundantSet=set()
    for i in range(len(setlist)):
        for j in range(i+1,len(setlist)):
            if(setlist[i]==setlist[j]):
                if(i==0):
                    redundantSet.add(i)
                redundantSet.add(j)
    print('You have redundant sets at index' + str(redundantSet))

您不能使用 any() 函数来等值值,因为 any() 只接受列表并且即使列表中有一个元素也会返回 true。所以即使这样做

any[(setlist[i+1:],setlist[i])

将返回 true,因为“setlist[i]”元素将在那里。因此,将返回 true。

【讨论】:

    【解决方案2】:

    有很多方法可以做到这一点。您可以迭代集合的数量,并且对于每 2 个集合,检查它们是否不相交。

    s1.isdisjoint(s2)
    

    如果两个集合中没有共同的元素,上述函数返回 True。

    s1 & s2
    

    上面的表达式返回集合 s1 和 s2 中的公共元素。

    any(i in s1 for i in s2)
    

    如果元素在 2 个集合中是公共的,则上述生成器表达式表达式返回一个布尔值 True。对于上述所有表达式,生成器表达式是最快的。第二快的是isdisjoint() 函数。设置交集s1 & s2 耗时最长,因此最慢。

    【讨论】:

      【解决方案3】:

      如果您想找到所有具有共同元素的集合对,这应该会有所帮助。您将希望使用内置的 set 函数,而不是进行元素比较。

      have_overlap = list()
      setlist = [s1, s2, s3, s4, s5]
      for ix1,s in enumerate(setlist):
        for ix2 in range(ix+1, len(setlist)):
          if s.symmetric_difference(setlist [ix2]):
            have_overlap.append(ix, ix2)
      

      【讨论】:

        【解决方案4】:

        一种解决方案可能是使用集合内置数据结构并比较每个集合。为此,您可以将所有集合放入字典中,并将键指定为 (1,2,3,5,6)。 要达到所有排列进行比较,您可以使用 itertools.product,例如:

        import itertools
        sets_1 = range(1,7)
        sets_2 = range(1,7)
        perms = list(filter(lambda x: x!=0, [(a,b) if a!= b else 0 for (a, b) in list(itertools.product(*[sets_1, sets_2]))]))
        

        通过使用 perms,您可以执行设置交集,例如:

        sets_dict= {1:{2,3}, 2:{5,6}, 3:{7,8}, 4:{5,9}, 5:{10,22}, 6:{22,4}}
        for (set_1, set_2) in perms:
            print(sets_dict[set_1] & sets_dict[set_2]) 
        

        或者,如果您的集合太大,您可以遍历每个集合并填写一个字典,其中键是集合成员,值是托管它们的集合。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-04-11
          • 2014-08-18
          • 2011-07-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多