Вот альтернативный подход, который работает, беря список всех 1 и рекурсивно сворачивая его, добавляя последующие элементы, это должно быть более эффективно, чем генерация всех возможных подмножеств:
def allSum(number):
def _collapse(lst):
yield lst
while len(lst) > 1:
lst = lst[:-2] + [lst[-2] + lst[-1]]
for prefix in _collapse(lst[:-1]):
if not prefix or prefix[-1] <= lst[-1]:
yield prefix + [lst[-1]]
return list(_collapse([1] * number))
>>> allSum(4)
[[1, 1, 1, 1], [1, 1, 2], [2, 2], [1, 3], [4]]
>>> allSum(5)
[[1, 1, 1, 1, 1], [1, 1, 1, 2], [1, 2, 2], [1, 1, 3], [2, 3], [1, 4], [5]]
Вы можете удалитьпоследнее значение, если вы не хотите тривиальный случай.Если вы просто просматриваете результаты, удалите вызов list
и просто верните генератор.