【问题标题】:python - split a list in pairs and unique elementspython - 成对拆分列表和唯一元素
【发布时间】:2015-07-12 11:27:30
【问题描述】:

我很难实现以下目标: 我有一个列表(例如,[a,b,c,d]),我需要以各种可能的方式将它分成对和唯一元素(顺序并不重要),即:

[a,b,c,d], [(a,b), c,d], [(a,b), (c,d)], [a, (b,c), d], [(a,d), (b, c)]...

等等。 This thread 解决了仅使用对时的问题,但我还需要独特的元素,但我无法做到这一点。 任何想法将不胜感激。 谢谢!

【问题讨论】:

    标签: python set partition


    【解决方案1】:

    也许更简单的解决方案是递归解决方案。 只需使用第一个元素创建每个组合,然后在没有它的情况下移动到子列表。

    def partition(L):
        if len(L) <= 1:
            return [L]
    
        partitions = [[L[0]] + p for p in partition(L[1:])]
        for i in xrange(1, len(L)):
            partitions.extend([[(L[0], L[i])] + p for p in partition(L[1:i]+L[i+1:])])
    
        return partitions
    

    【讨论】:

    • 我承认,这很简单。
    【解决方案2】:

    给定一个给出偶数长度列表的函数,将其成对拆分而不考虑顺序:

    def gen_only_pairs(l):
        if not l:
            yield []
            return
    
        for i in xrange(1, len(l)):
            l[1], l[i] = l[i], l[1]
            for v in gen_only_pairs(l[2:]):
                yield [(l[0], l[1])] + v
            l[1], l[i] = l[i], l[1]
    

    我们可以生成我们想要的结果:

    from itertools import combinations
    
    def gen(a):
        # For all number of pairs
        for npairs in xrange(0, len(a) // 2 + 1): 
            # For each combination of 2 * npairs elements
            for c in combinations(a, 2 * npairs):
                rest = list(set(a) - set(c))
                # Generate all splits of combination into pairs
                for v in gen_only_pairs(list(c)):
                    # Also add the rest of the elements
                    yield v + rest
    

    并像这样使用:

    for c in gen([1, 2, 3, 4]):
        print c
    

    输出:

    [1, 2, 3, 4]
    [(1, 2), 3, 4]
    [(1, 3), 2, 4]
    [(1, 4), 2, 3]
    [(2, 3), 1, 4]
    [(2, 4), 1, 3]
    [(3, 4), 1, 2]
    [(1, 2), (3, 4)]
    [(1, 3), (2, 4)]
    [(1, 4), (3, 2)]
    

    【讨论】:

    • 我会研究你的答案,非常感谢,以后,我想从[1, 2, 3, 4, 5, 6] => [(1, 2 , 3), (4, 5, 6)], [(1, 2, 3), (4, 5), 6], [(1, 2, 3), 4, (5, 6)], [ (1, 2, 3), (4, 6), 5)], [(1, 2, 3), 4, 6, 5)]等
    【解决方案3】:

    使用来自itertools的组合:

    from itertools import combinations
    
    data = ['a', 'b', 'c', 'd']
    pairs = [i for i in combinations(data, 2)]
    >>> pairs
    [('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd'), ('c', 'd')]
    
    triplets = [i for i in combinations(data, 3)]
    >>> triplets
    [('a', 'b', 'c'), ('a', 'b', 'd'), ('a', 'c', 'd'), ('b', 'c', 'd')]
    

    等等

    【讨论】:

      【解决方案4】:

      好的!让我们看看,这不是我能想到的最漂亮的,我很确定我们可以从中删减几行,但至少它是通用的(将元组提取到最大大小),我想与你们!

      from itertools import permutations
      
      thelist = ['a', 'b', 'c', 'd']
      
      def tuplets(l, max):
          out = []
          for i in permutations(l):
              for j in xrange(1, max + 1):
                  pick(list(i), max, out, [], j, 0)
          return out
      
      def pick(l, max, out, branch, num, idx):
          if (num == 1):
              picked = l[idx]
          else:
              picked = tuple(l[idx:idx+num])
      
          newBranch = list(branch)
          newBranch.append(picked)
      
          if idx + num == len(l):
              out.append(newBranch)
              return
      
          for i in xrange(1, max + 1):
              if idx + i + num > len(l):
                  continue
              pick(l, max, out, newBranch, i, idx + num)
      
      print tuplets(thelist, 2)
      

      【讨论】:

        猜你喜欢
        • 2019-04-10
        • 1970-01-01
        • 2014-06-02
        • 2021-03-17
        • 2013-12-28
        • 1970-01-01
        • 2013-08-24
        • 1970-01-01
        • 2019-11-24
        相关资源
        最近更新 更多