python комбинации разделения списка

#python #recursion #combinations #combinatorics

Вопрос:

Учитывая два входных аргумента:

x : lt;listgt; как [0, 1, 2, 3]

splits : lt;listgt; int представления числа и длины разбиений, например [1, 2, 1] . Это означает, что список должен быть разделен на 3, 1-й содержит 1 элемент, 2-й содержит 2 элемента, а 3-й раздел содержит 1 элемент

Мне нужна функция, которая возвращает все возможные комбинации расщеплений, например:

def get_combos(x, splits): ...

gt;gt;gt; get_combos([0, 1, 2, 3], [1, 2, 1])

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

Входные данные всегда будут соответствовать этим условиям:

  • min(splits) gt;= 1 —gt; В разделении всегда есть элемент
  • sum(splits) == len(x) —gt; Все элементы в gt; x взяты

Каков наилучший способ сделать это рекурсивно?

Комментарии:

1. почему вы хотите делать это рекурсивно? кроме того, обычно больше шансов получить ответ, если вы уже пытались это сделать … вот вам подсказка … учитывая список, сделайте точные указанные разбиения … начните с создания функции, которая просто берет список и некоторые длины разбиения и возвращает новый разделенный список

Ответ №1:

Вы можете использовать рекурсивную функцию генератора:

 def combos(a, b, c = []):  if not a or not b:  yield [*map(tuple, c)]  else:  for x, y in enumerate(a):  if not c or len(c[-1]) == b[0]:  yield from combos(a[:x] a[x 1:], b[1:] if c else b, c [[y]])  else:  yield from combos(a[:x] a[x 1:], b, [*c[:-1], c[-1] [y]])  print(list(combos([0, 1, 2, 3], [1, 2, 1])))  

Выход:

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

Комментарии:

1. Спасибо Ajax, к сожалению, он не работает на моем python, у меня IndexError в последней строке кода, кажется c , пусто, и вызов c[-1] вызывает исключение

2. @NiSi Пожалуйста, опубликуйте ввод, который вызывает ошибку.

3. Извините, Аякс, мой плохой, неправильный отступ последнего слова (под » для «вместо » если»). Еще раз спасибо вам