Python:一个列表中所有列表的组合

5

我有一个字符串列表的列表

[['a','b'],['c','d'],['e','f']]

我想获得所有可能的组合,以使结果为

[['a','b'],['c','d'],['e','f'],
 ['a','b','c','d'],['a','b','e','f'],['c','d','e','f'],
 ['a','b','c','d','e','f']]

到目前为止,我已经想出了这段代码片段。
input = [['a','b'],['c','d'],['e','f']]
combs = []
for i in xrange(1, len(input)+1):
    els = [x for x in itertools.combinations(input, i)]
    combs.extend(els)
print combs

大部分参考了这篇帖子中的答案。

但是结果是:

[(['a','b'],),(['c','d'],),(['e','f'],),
 (['a','b'],['c','d']),(['a','b'],['e','f']),(['c','d'],['e','f']),
 (['a','b'],['c', 'd'],['e', 'f'])]

我目前遇到了难题,正在尝试寻找一种优雅、Pythonic的方法来解包这些元组。

4个回答

7

您可以使用itertools.chain.from_iterable将列表的元组压缩为列表。 示例-

import itertools
input = [['a','b'],['c','d'],['e','f']]
combs = []
for i in xrange(1, len(input)+1):
    els = [list(itertools.chain.from_iterable(x)) for x in itertools.combinations(input, i)]
    combs.extend(els)

演示 -
>>> import itertools
>>> input = [['a','b'],['c','d'],['e','f']]
>>> combs = []
>>> for i in range(1, len(input)+1):
...     els = [list(itertools.chain.from_iterable(x)) for x in itertools.combinations(input, i)]
...     combs.extend(els)
...
>>> import pprint
>>> pprint.pprint(combs)
[['a', 'b'],
 ['c', 'd'],
 ['e', 'f'],
 ['a', 'b', 'c', 'd'],
 ['a', 'b', 'e', 'f'],
 ['c', 'd', 'e', 'f'],
 ['a', 'b', 'c', 'd', 'e', 'f']]

1
不错。我经常惊叹于itertools的强大。 - John Coleman
完美。正是我所寻找的。谢谢! - Matt M.

0

实现这个目标的一个想法是将整数从[0..2**n-1]映射到所有目标元素,根据一个非常简单的规则:如果(2**k)&i!=0,则取索引为k的元素,其中i在[0..2**n-1]范围内运行。换句话说,i必须按位读取,并且对于每个设置的位,保留l中相应的元素。从数学角度来看,这是实现所需操作最清晰的方法之一,因为它非常接近集合部分的定义(对于具有n个元素的集合,您恰好有2**n个部分)。

没有尝试过,但类似这样的代码应该可以工作:

l = [['a','b'],['c','d'],['e','f']]                                                    
n = len(l)
output = []
for i in range(2**n):
    s = []
    for k in range(n):
        if (2**k)&i: s = s + l[k]
    output.append(s)

如果您不想要空列表,只需将相关行替换为:

for i in range(1,2**n):

0
如果你想要所有的组合,可以考虑这种简单的方法:
import itertools

a = [['a','b'],['c','d'],['e','f']]
a = a + [i + j for i in a for j in a if i != j] + [list(itertools.chain.from_iterable(a))]

如果原始列表包含4个列表,则此列表不会包含长度为3的结果组合。 - Matt M.
@Matt M. 是的,你说得对,我没有考虑到列表包含4个列表,只是展示了一个简单的情况。如果有超过3个列表的情况,Anand S Kumar的方法将是你需要的。谢谢你让我知道。 - Fei Yuan

0

使用列表推导式:

combs=[sum(x,[]) for i in range(len(l)) for x in itertools.combinations(l,i+1)]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接