获得可迭代列表的组合的优雅方式

时间:2013-03-07 20:36:01

标签: python itertools

我有一个可迭代对象的列表,我有兴趣获得每个迭代中包含0或1个项目的所有列表(顺序不重要,所以它的组合不是我寻求的排列)。

我在下面发布了一个非常不优雅的实现。

我确信有一种更优雅的方式可以做到这一点,可能使用itertools模块,但我无法想出任何东西。有什么建议吗?


import itertools


def all_subsets(ss):
    subset_lens = range(0, len(ss) + 1)
    list_of_subsets = map(lambda n: itertools.combinations(ss, n), subset_lens)
    return itertools.chain.from_iterable(list_of_subsets)


list_of_iterables = [["A1"], ["B1", "B2", "B3"], ["C1", "C2"]]

all_possibilities = itertools.chain.from_iterable(itertools.product(*subset)
                                for subset in all_subsets(list_of_iterables))

# Visual representation of the desired result
for eg in all_possibilities:
    print eg

结果:

()
('A1',)
('B1',)
('B2',)
('B3',)
('C1',)
('C2',)
('A1', 'B1')
('A1', 'B2')
('A1', 'B3')
('A1', 'C1')
...

2 个答案:

答案 0 :(得分:1)

这就是我想出来的......

data = [["A1"], ["B1", "B2", "B3"], ["C1", "C2"]]
data = [[None] + x for x in data]
data = sorted(filter(None, x) for x in itertools.product(*data))
for result in data:
    print result

输出:

()
('A1',)
('A1', 'B1')
('A1', 'B1', 'C1')
('A1', 'B1', 'C2')
('A1', 'B2')
('A1', 'B2', 'C1')
('A1', 'B2', 'C2')
('A1', 'B3')
('A1', 'B3', 'C1')
('A1', 'B3', 'C2')
('A1', 'C1')
('A1', 'C2')
('B1',)
('B1', 'C1')
('B1', 'C2')
('B2',)
('B2', 'C1')
('B2', 'C2')
('B3',)
('B3', 'C1')
('B3', 'C2')
('C1',)
('C2',)

答案 1 :(得分:1)

[filter(None, comb) for comb in itertools.product(*[[None] + it for it in list_of_iterables])]

这使得一些简化假设成为可能。如果您的iterables包含在布尔上下文中不为true的值,则必须使用更复杂的filter。如果您的iterables不是列表,则必须使用itertools.chain而不是[None] + it