生成列表的所有有序组合,其中每个组合包括所有项目

时间:2017-05-01 20:05:03

标签: python list combinations

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

例如,对于列表['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开始的所有组合中,然后查找下一个项目并查找以该项目开头的所有组合,依此类推。我认为这不会有效率。

3 个答案:

答案 0 :(得分: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)]

除非您先将它们转换为字符串,否则这对数字不起作用。

答案 1 :(得分:1)

这是在int的帮助下为char.isdigit()提供@acidtobi答案工作的附加代码。

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']]

答案 2 :(得分:1)

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']]