【问题标题】:How to Find All Combination of a List of size from 1 to length of list (Without Itertools)如何查找大小从 1 到列表长度的列表的所有组合(没有 Itertools)
【发布时间】:2020-10-29 16:21:20
【问题描述】:

是否有一种简单的算法(很可能是递归算法)可以找到列表和所有大小的所有组合(从大小为 1 的组合到列表大小长度的组合)?

例如:如果我有一个列表 = [1, 2, 3, 4],我应该得到的所有尺寸的组合是:

[1], [2], [3], [4], [1,2], [1,3], [1,4], [2,3], [2,4], [ 3,4], [1,2,3], [1,2,4], [1,3,4], [2,3,4], [1,2,3,4]。

所以我只知道我在网上找到的一种递归算法,它可以找到大小 n 的组合,但不是针对从 1 到列表长度的所有大小。组合中的顺序无关紧要。

这是我在网上找到的代码:

def n_length_combo(lst, n): 
  
    if n == 0: 
        return [[]] 
  
    l =[] 
    for i in range(0, len(lst)): 
      
        m = lst[i] 
        remLst = lst[i + 1:] 
      
        for p in n_length_combo(remLst, n-1): 
            l.append([m]+p) 
          
    return l

这仅适用于大小为 n 的组合。但我想找到从 1 到列表长度的所有尺寸的组合。

这里有什么想法吗?

【问题讨论】:

  • 你看过itertools模块吗?
  • 我正在尝试不使用任何迭代工具

标签: python recursion combinations


【解决方案1】:

使用 len 函数以列表的长度调用它:

n_length_combo(lst, len(lst))

更好的是,如果您不想总是传递第二个参数,您可以指定一个默认值:

def n_length_combo(lst, n=len(lst)): 

【讨论】:

    【解决方案2】:

    见下文(使用itertools

    from itertools import combinations
    
    lst = [1, 2, 3, 4]
    final_lst = []
    for x in lst[1:]:
        final_lst.extend(combinations(lst, r=x))
    print(final_lst)
    

    输出

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

    【讨论】:

      【解决方案3】:

      对于列表中的每个元素:您可以选择该元素,也可以不选择它。 这给了我们一个递归公式:

      combinations(l) = combinations(l[:-1]) + [add l[-1] to every element of combinations(l[:-1])
      

      这给了我们一个递归算法:

      def combinations(l):
        if not l:
          return [[]]
        else:
          c = combinations(l[:-1])
          return c + [r+[l[-1]] for r in c]
      
      print(combinations(range(4)))
      # [[], [0], [1], [0, 1], [2], [0, 2], [1, 2], [0, 1, 2], [3], [0, 3], [1, 3], [0, 1, 3], [2, 3], [0, 2, 3], [1, 2, 3], [0, 1, 2, 3]]
      

      当然不需要递归:

      def combinations(l):
        c = [[]]
        for x in l:
          c = c + [r+[x] for r in c]
        return c
      
      print(combinations(range(4)))
      # [[], [0], [1], [0, 1], [2], [0, 2], [1, 2], [0, 1, 2], [3], [0, 3], [1, 3], [0, 1, 3], [2, 3], [0, 2, 3], [1, 2, 3], [0, 1, 2, 3]]
      

      【讨论】:

        【解决方案4】:

        使用您拥有的功能,但收集您需要的所有组合长度的结果:

        L = [1,2,3,4]
        result = []
        for n in range(1,len(L) + 1):
            result.extend(n_length_combo(L,n))
        print(result)
        

        输出:

        [[1], [2], [3], [4], [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4], [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4], [1, 2, 3, 4]]
        

        这是一个完整的递归生成器:

        def all_combo(lst): 
            def n_combo(lst,n):
                if n == 1: 
                    yield from ([n] for n in lst)
                for i,item in enumerate(lst):
                    for combo in n_combo(lst[i+1:],n-1):
                        yield [item] + combo
            for n in range(1,len(lst)+1):
                yield from n_combo(lst,n)
        
        L = list(all_combo([1,2,3,4]))
        print(L)
        

        输出:

        [[1], [2], [3], [4], [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4], [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4], [1, 2, 3, 4]]
        

        【讨论】:

        • 这是在函数之外还是递归步骤?
        • @DewMan 函数外。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-21
        • 1970-01-01
        • 2017-11-27
        • 1970-01-01
        相关资源
        最近更新 更多