Прежде всего, если вам на самом деле не нужно реализовывать это самостоятельно, стандартная библиотека с радостью поможет .
Но это интересная проблема для изучения рекурсии, поэтому давайте возьмем
Аналогично здесь , для сложных случаев использования рекурсии, которые а) делают несколько рекурсивных вызовов одновременно и б) должны каким-то образом "накапливать" результаты, мойРекомендую написать рекурсивный генератор. Вы можете преобразовать его механически:
заменить print
на yield
yield from
рекурсивные вызовы (как я отметил надругой ответ там, для случаев, когда вам не нужно накапливать результаты, вы, как правило, хотели бы return
эти).
Затем из-за пределов рекурсии вы можете собрать результатыв list
, или итерируйте их напрямую.
Однако есть и проблема с вашим алгоритмом: результаты, в которых отсутствуют два или более исходных элемента, будут появляться более одного раза (как вы уже можетевидите), потому что существует более одного рекурсивного «пути» к ним. Вместо этого вам нужен следующий алгоритм:
- Рекурсивно получить подмножества, не включающие в себя первый элемент
- Для каждого из них выведите два результата: один с добавленным первым элементом иодин без
Так что вместо yield from
мы будем перебирать результаты, делать некоторые изменения и yield
внутри этого цикла.
Собирая все это вместе, похоже:
def power_set(items):
if not items: # empty set; base case for recursion.
yield items
return
# Pull off the first element,
first, *rest = items
# then iterate over the recursive results on the rest of the elements.
for without_first in power_set(rest):
yield [first] + without_first
yield without_first
# let's test it:
list(power_set([1,2,3]))
# [[1, 2, 3], [2, 3], [1, 3], [3], [1, 2], [2], [1], []]
# Good, just what we want - with no duplicates.