如何从列表中获取“子”列表的所有组合

时间:2018-09-21 22:45:47

标签: python

所以,如果我从以下内容开始:

x = [a, b, c]
y = [[a], [b], [c], [a,b], [b,c]]

如何从x中的元素中获取可以构成y的所有组合?像这样:

y = [ [[a, b], c], [[b,c], a], [a, b, c]

我已经研究过itertools和列表理解功能,但是仍然很挣扎。 原始列表中的所有元素都必须出现在结果列表的每个项目中。

3 个答案:

答案 0 :(得分:0)

如何获得列表中每个项目的组合?

遍历列表,然后在该循​​环内再次遍历列表:

x = [a, b, c]
y = []
for i in x:
    for j in x:
        y.append([i, j])

请注意,您要求的确切输出不是“列表中每个项目的组合”-实际上,您的确切输出似乎没有一致性,这意味着标准库中的任何内容都不会帮助您,但这应该为您提供一个起点。

答案 1 :(得分:0)

您可以将递归函数与生成器一起使用:

def full_length(d):
  return sum(1 if not isinstance(i, list) else full_length(i) for i in d)

def semi_combos(d, current=[]):
   if len(current) == len(x) - 1:
     yield current
   else:
     for i in d:
       if len(set(current+[i])) == len(current)+1:
         yield from semi_combos(d, current+[i])

def remainder_combos(d, _target, current = []):
  if full_length(current)+len(_target) == len(x):
    yield [_target, *current]
  for i in d:
    if i not in _target and i not in current:
      yield from remainder_combos(d, _target, current+[i])


for x in [['a', 'b', 'c'], ['a', 'b', 'c', 'd']]:
  print([b for i in semi_combos(x) for b in list(remainder_combos(x, i))])

输出:

[[['a', 'b'], 'c'], [['a', 'c'], 'b'], [['b', 'a'], 'c'], [['b', 'c'], 'a'], [['c', 'a'], 'b'], [['c', 'b'], 'a']]

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

答案 2 :(得分:0)

现在假设您具有可以使用的有效组合列表。使用递归函数,我可以获得所需的输出。

注意:我已经做了0次优化

import numpy


def build_combo(current_set, all_combos):
    global count, req_options
    for each in all_combos:
        if all(len(numpy.intersect1d(each, x)) == 0 for x in current_set):
            inner_set = current_set.copy()
            inner_set.append(each)
            flat = []
            for x in inner_set:
                flat.extend(x)
            if all(x in flat for x in req_options):
                built_combos.append(inner_set)
            else:
                build_combo(inner_set, all_combos)


req_options = ['a', 'b', 'c', 'd', 'e', 'f', 'g']

all_combos = [['a'], ['b'], ['c'], ['d'], ['e'], ['f'], ['g'],
              ['a', 'b'], ['c', 'd'], ['a', 'f'], ['f', 'g'],
              ['a', 'c', 'd'], ['g', 'f', 'e', 'b']]

built_combos = []
build_combo([], all_combos)

option_sets = set()
for combo in built_combos:
    newset = set()
    for element in combo:
        newset.add(frozenset(element))
    option_sets.add(frozenset(newset))

for option_set in option_sets:
    combo_str = ''
    for option in option_set:
        combo_str += '[{}]'.format('+'.join(option))
    print(combo_str)

输出(在打印输出上添加了“ +”号,以便于阅读):

[e][g][c+d][b][f+a]
[a][c][d][f+e+g+b]
[f+g][e][c][d][a+b]
[f+g][e][c+d][a][b]
[f][e][c][g][a][b][d]
[c+a+d][f][e][g][b]
[b][e][f+g][c+a+d]
[f][e][g][c+d][a+b]
[f+g][e][a+b][c+d]
[f][e][g][c+d][a][b]
[e][c][g][b][f+a][d]
[f+g][e][c][a][b][d]
[f][e][c][g][d][a+b]
[a][f+e+g+b][c+d]
[c+a+d][f+e+g+b]