Вы можете использовать рекурсию с генератором:
def op(d, n, _d, c = []):
if _d == 1:
yield c
else:
for i in d:
if sum(isinstance(h, list) or h not in {'AND', 'OR'} for h in c) == n:
yield from op(d, n, _d-1, c=[c, 'OR', i])
yield from op(d, n, _d-1, c=[c, 'AND', i])
else:
if not c:
yield from op(d, n, _d, c=[i])
else:
yield from op(d, n, _d, c=[*c, 'OR', i])
yield from op(d, n, _d, c=[*c, 'AND', i])
result = list(op(['A','B','C','D'], 2, 2))
Выход (первые десять результатов):
[[['A', 'OR', 'A'], 'OR', 'A'], [['A', 'OR', 'A'], 'AND', 'A'], [['A', 'OR', 'A'], 'OR', 'B'], [['A', 'OR', 'A'], 'AND', 'B'], [['A', 'OR', 'A'], 'OR', 'C'], [['A', 'OR', 'A'], 'AND', 'C'], [['A', 'OR', 'A'], 'OR', 'D'], [['A', 'OR', 'A'], 'AND', 'D'], [['A', 'AND', 'A'], 'OR', 'A'], [['A', 'AND', 'A'], 'AND', 'A']]
Это решение позволит вам контролировать длину и глубину каждогоэлемент в result
.Например, при генерации на глубину 4
:
result = list(op(['A','B','C','D'], 2, 4))
print(result[:10])
Вывод:
[[[[['A', 'OR', 'A'], 'OR', 'A'], 'OR', 'A'], 'OR', 'A'], [[[['A', 'OR', 'A'], 'OR', 'A'], 'OR', 'A'], 'AND', 'A'], [[[['A', 'OR', 'A'], 'OR', 'A'], 'OR', 'A'], 'OR', 'B'], [[[['A', 'OR', 'A'], 'OR', 'A'], 'OR', 'A'], 'AND', 'B'], [[[['A', 'OR', 'A'], 'OR', 'A'], 'OR', 'A'], 'OR', 'C'], [[[['A', 'OR', 'A'], 'OR', 'A'], 'OR', 'A'], 'AND', 'C'], [[[['A', 'OR', 'A'], 'OR', 'A'], 'OR', 'A'], 'OR', 'D'], [[[['A', 'OR', 'A'], 'OR', 'A'], 'OR', 'A'], 'AND', 'D'], [[[['A', 'OR', 'A'], 'OR', 'A'], 'AND', 'A'], 'OR', 'A'], [[[['A', 'OR', 'A'], 'OR', 'A'], 'AND', 'A'], 'AND', 'A']]