【问题标题】:Python set comparisonPython集比较
【发布时间】:2012-07-12 09:10:37
【问题描述】:

我有两组,每组包含许多元组:

s1 = set([('a','b','c'), ('d','e','f'), ('g','h','i'), ('j','k','l'), ('m','n','o')])
s2 = set([('a','y','z'), ('p','q','r'), ('s','t','u'), ('v','w','x')])

每个元组包含多个字符串(在本例中为 3)。此外,每个元组都有一个 id,它是第一个元素。我想检查哪个元组在两个集合中具有相同的 id,但后面的值不同,例如 s1 中的 (a,b,c) 和 s2 中的 (a,y,z) 并输出。

您是否必须拥有确切的元组才能使用 in 检查它是否在集合中,然后如何访问该元组以将其打印出来?

【问题讨论】:

  • 此外,每个元组都有一个 id,它是第一个元素。 听起来你真的想改用 dicts..

标签: python comparison set


【解决方案1】:

你必须有确切的元组来检查它是否在使用 in 的集合中

是的,你知道。如果只需要比较部分项目,请使用dict,将可比较的部分设为键,其余部分设为值。

从您的示例代码开始,

d1 = dict((x[0], x) for x in s1)
# similarly, make d2 from s2

然后您可以检查a in d1,获取与d1[a] 关联的三元组等。

【讨论】:

    【解决方案2】:

    我认为将您的集合转换为dicts 会简化搜索:

    >>> d1 = {t1[0]: (t1[1], t1[2]) for t1 in s1}
    >>> d1
    {'a': ('b', 'c'), 'j': ('k', 'l'), 'm': ('n', 'o'), 'd': ('e', 'f'), 'g': ('h', 'i')}
    >>> d2 = {t2[0]: (t2[1], t2[2]) for t2 in s2}
    >>> d2
    {'a': ('y', 'z'), 'p': ('q', 'r'), 's': ('t', 'u'), 'v': ('w', 'x')}
    >>> [(k2, d2[k2]) for k2 in d2 if k2 in d1 and d2[k2] != d1[k2]]
    [('a', ('y', 'z'))]
    

    【讨论】:

      【解决方案3】:

      将您的集合转换为字典,使用 id 作为字典的键:

      s1d = {}
      for e in s1:
        s1d[e[0]] = e
      

      那应该很容易了。

      【讨论】:

        【解决方案4】:

        这样的东西可以工作:

        for x in s1:
           templist = [y for y in s2 if y[0] == x[0] and x[1:] != y[1:]]
           if len(templist):
              print x,
        

        【讨论】:

        • 如果速度是个问题,这将不会发生,因为它是O(n^2)
        • 是的,但是所有使用哈希的方法都差不多,不是吗?必须将集合转换为散列,然后必须在另一个散列中搜索一个键,最终必须以某种方式实现对另一个散列中的每个键的搜索。那么O(n^2)可以避免吗?
        • 实现是不变的,在增长中没有考虑。我想你是在谈论时间。
        • 我不太明白你的意思。我们要取出一组中的每个元素,检查另一组中是否存在,如果存在,则打印出来。由于我们处理的是集合,因此保证了元素是唯一的,因此没有进一步的范围可以重用历史来跳过对某些后续元素的搜索。所以它必须是 O(n^2) 搜索一种方式或另一种方式,如何避免?
        • 当您只是想检查集合中是否存在某些内容时,重复不是问题。在我的解决方案中,我只检查交叉点中的键,这是一个平均情况 O(N) 操作,因为设置的平均查找时间是 O(1),那O(N^2) 怎么样?
        【解决方案5】:

        您想使用 dict 而不是 set 来按 id 存储项目:

        def byid(tups):
            for t in tups:
                # yield key, value paris
                yield t[0], tuple(t[1:])
        
        # make a dict from the pairs
        seen = dict(byid(s1))
        
        for key, vals in byid(s2):
            # now it's easy to find duplicates
            if key in seen:
                print seen[key], "vs", vals
        

        【讨论】:

          【解决方案6】:

          正如@MartijnPieters 所说,您应该使用字典。

          这是@larsmans 提出的解决方案。

          >>> s1 = set([('a','b','c'), ('d','e','f'), ('g','h','i'), ('j','k','l'), ('m','n','o')])
          >>> s2 = set([('a','y','z'), ('p','q','r'), ('s','t','u'), ('v','w','x')])
          >>> d1 = dict((i, (a, b)) for i, a, b in s1)
          >>> d2 = dict((i, (a, b)) for i, a, b in s2)
          >>> [(k, d1[k], d2[k]) for k in set(d1).intersection(d2) if d1[k] != d2[k]]
          [('a', ('b', 'c'), ('y', 'z'))]
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-09-18
            • 1970-01-01
            • 1970-01-01
            • 2022-11-16
            相关资源
            最近更新 更多