Все комбинации элементов списка python - функциональный стиль

Требуется функция, которая возвращает список, со всевозможными комбинациями элементов входящего списка, но написанная в функциональном стиле. То есть без присваивания, циклов... Рекурсия приветствуется.

Для примера, у меня есть похожая, но она возвращает не все значения:

def f (s, n):
    return [s[:n+1]]+[s[n+1:]]

def f2 (s, n):
    return [] if n > len(s)-1 else f(s,n) + f2(s,n+1)

print(f2([1,2,3,0))

Возвращает:

[[1], [2, 3], [1, 2], [3], [1, 2, 3], []]

А мне требуется:

[[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]

Ответы (2 шт):

Автор решения: Stanislav Volodarskiy

Не очень эффективно, но работает:

def prepend(e, lists):
    if len(lists) == 0:
        return []
    return [[e] + lists[0]] + prepend(e, lists[1:])


def duplicate(e, lists):
    return lists + prepend(e, lists)


def f(s):
    if len(s) == 0:
        return [[]]
    return duplicate(s[0], f(s[1:]))


print(f([1,2,3]))
→ Ссылка
Автор решения: extrn
import functools

def f(it):
    return functools.reduce(lambda y, x: y + [z + [x] for z in y], it, [[]])
print(f([1, 2, 3])) # [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]

И на всякий случай: for здесь не цикл, а генератор списка, т.е. функциональная конструкция. Но если очень хочется, можно заменить на map.

→ Ссылка