【问题标题】:Generate all ordered combinations of a list, where each combination includes all items生成列表的所有有序组合,其中每个组合包括所有项目
【发布时间】:2017-05-01 20:05:03
【问题描述】:

生成列表的所有组合的最佳方式是什么,其中每个组合都包含列表中的每个项目,并且您可以在其中组合其他项目。

例如,对于一个列表['a','b','c'],我喜欢生成:

['a','b','c']
['ab','c']
['a','bc']
['abc']

我觉得它有点类似于:Python: Generating all ordered combinations of a list。但是这个只关心切片。我想要从列表中获取每个项目的所有组合。是否有来自 itertools 的内置函数可用于生成答案?

列表也可以是数字,可能有重复值。例如:[1,2,1] 应该生成:

[1,2,1]
[12,1]
[1,21]
[121]

我可以尝试使用链接中的代码,但不是生成项目组合,而是根据列表的索引生成组合。我取所有以 0 开头的组合,然后查找下一个项目并查找以该项目开头的所有组合,依此类推。不过我认为这不会有效。

【问题讨论】:

    标签: python list combinations


    【解决方案1】:

    您可以将字符串中的两个相邻字符视为“分隔”或“连接”。使用itertools.product(),您可以生成两个字符之间分隔/连接的所有组合,然后使用一个简单的函数根据这些信息生成字符串列表:

    import itertools
    
    l = ['a','b','c']
    
    def generate_combination(source, comb):
        res = []
        for x, action in zip(source,comb + (0,)):
            res.append(x)
            if action == 0:
                yield "".join(res)
                res = []
    
    print [list(generate_combination(l,c)) 
           for c in itertools.product((0,1), repeat=len(l)-1)]
    

    这不适用于数字,除非您先将它们转换为字符串。

    【讨论】:

    • 这似乎工作正常。只是想看看它是如何工作的。
    • 我刚刚了解了您的生成器功能,它非常酷。感谢您的回答。
    【解决方案2】:

    .isdigit() 的帮助下,这是使@acidtobi 回答同时适用于intchar 的附加代码。

    final = [list(generate_combination(l,c)) 
           for c in itertools.product((0,1), repeat=len(l)-1)]
    
    print [[int(i) if i.isdigit() else i for i in alist ] for alist in final]
    

    所以对于 l = [ 1,2,3] ,它会显示

    >>> 
    [[1, 2, 3], [1, 23], [12, 3], [123]]
    

    对于l = ['a','b','c']

    >>> 
    [['a', 'b', 'c'], ['a', 'bc'], ['ab', 'c'], ['abc']]
    

    【讨论】:

      【解决方案3】:
      import numpy as np
      l = ['a','b','c','d']
      #l = [0,1,2,3]
      d = np.arange(2**(len(l)-1))
      #create a separator array for all possible combinations
      sep = np.where((d[:,None] & (1 << np.arange(len(l))[::-1])) > 0, ',','')
      #merge the separator to the strings
      merged = np.core.defchararray.add(sep,np.asarray(l,dtype=str)).tolist()
      #reformat and split
      [''.join(e).split(',') for e in merged]
      
      #works for any characters
      [['abcd'],
       ['abc', 'd'],
       ['ab', 'cd'],
       ['ab', 'c', 'd'],
       ['a', 'bcd'],
       ['a', 'bc', 'd'],
       ['a', 'b', 'cd'],
       ['a', 'b', 'c', 'd']]
      
      Out[128]: 
      [['0123'],
       ['012', '3'],
       ['01', '23'],
       ['01', '2', '3'],
       ['0', '123'],
       ['0', '12', '3'],
       ['0', '1', '23'],
       ['0', '1', '2', '3']]
      

      【讨论】:

        猜你喜欢
        • 2015-10-13
        • 2020-02-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-16
        • 2015-10-15
        • 1970-01-01
        相关资源
        最近更新 更多