在python中创build一个列表的所有可能的组合

我需要能够创build一个包含input列表的所有可能组合的列表。 例如,列表[1,2,3]应该返回[1 [1,2] [1,3] 2 [2,3] 3 [1,2,3]]列表不一定要在特定的顺序。 在这个网站上,我发现了很多使用itertools的函数,但是当我只需要一个列表时,这些函数就是返回对象。 我是一个Python编码的初学者,所以任何想法或想法将不胜感激。

只需使用itertools.combinations 。 例如:

 import itertools lst = [1, 2, 3] combs = [] for i in xrange(1, len(lst)+1): combs.append(i) els = [list(x) for x in itertools.combinations(lst, i)] combs.append(els) 

现在combs拥有这个值:

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

是的,它与您提供的样本输出略有不同,但在该输出中,您没有列出所有可能的组合。

我在每个大小的实际列表之前列出了组合的大小,如果你需要的只是组合(没有大小,因为它出现在你的示例输出中),然后尝试这些其他版本的代码:

 import itertools lst = [1, 2, 3] combs = [] for i in xrange(1, len(lst)+1): els = [list(x) for x in itertools.combinations(lst, i)] combs.extend(els) 

现在combs拥有这个值:

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

你可以在循环中使用itertools.combinations来解决你的问题:

 >>> l = [1,2,3] >>> comb = [] >>> for i in range(len(l)): ... comb += itertools.combinations(l,i+1) ... >>> comb [(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)] 

如果你想要他们作为一个列表:

 >>> comb_list = [ list(t) for t in comb ] >>> comb_list [[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]] 

编辑:组合的第一个参数是可迭代的,第二个是所得元组的长度(在这种情况下,从1len(l) )。

有关组合的更多信息: http : //docs.python.org/library/itertools.html#itertools.combinations

itertools模块的函数返回迭代器。 所有你需要做的将这些转换成列表是调用list()结果。

但是,由于您需要三次分别调用itertools.combinations (每次调用一次),您可以使用list.extend将迭代器的所有元素添加到最终列表中。

尝试以下操作:

 import itertools in_list = [1, 2, 3] out_list = [] for i in range(1, len(in_list)+1): out_list.extend(itertools.combinations(in_list, i)) 

或者作为列表理解:

 out_list = [c for i in range(len(in_list)) for c in itertools.combinations(in_list, i+1)] 

这将导致以下列表:

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

如果你想要列表而不是元组,并且将单个长度的元组转换为值,你可以执行以下操作:

 out_list = [x[0] if len(x) == 1 else list(x) for x in out_list] # [1, 2, 3, [1, 2], [1, 3], [2, 3], [1, 2, 3]] 

或者将单个项目保留为列表:

 out_list = map(list, out_list) 

itertools模块确实返回生成器而不是列表,但是:

  • 生成器通常比列表更有效率(特别是如果您生成大量的组合)
  • 当你真的需要的时候,你总是可以使用list(...)将生成器转换为列表

itertoolschaincombinations函数运行良好 ,但是您需要使用Python 2.6或更高版本:

 import itertools def all_combinations(any_list): return itertools.chain.from_iterable( itertools.combinations(any_list, i + 1) for i in xrange(len(any_list))) 

你可以这样称呼它:

 # as a generator all_combinations([1,2,3]) # --> <itertools.chain at 0x10ef7ce10> # as a list list(all_combinations([1,2,3])) # --> [(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)] # as a list of lists [list(l) for l in all_combinations([1,2,3])] # --> [[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]] 

如果您之前没有使用过生成器,请注意您将它们循环,就好像它们是列表一样,例如:

 # a generator returned instead of list my_combinations = all_combinations([1,2,3]) # this would also work if `my_combinations` were a list for c in my_combinations: print "Combo", c """ Prints: Combo (1,) Combo (2,) Combo (3,) Combo (1, 2) Combo (1, 3) Combo (2, 3) Combo (1, 2, 3) """ 

性能差异可能很大。 如果您比较性能,您会看到生成器的创build速度要快得多:

 # as a generator all_combinations(range(25)) # timing: 100000 loops, best of 3: 2.53 µs per loop # as a list list(all_combinations(range(25))) # timing: 1 loops, best of 3: 9.37 s per loop 

请注意,无论在哪种情况下都要花费一些时间来遍历所有的组合,但是对于您来说这可能是一个巨大的胜利,特别是如果您在早期find您想要的内容的话。