Разделил подготовку индексов и выбор индексов.
>>> import itertools
>>>
>>> def find_all(nums, target):
... out = []
... length = len(nums)
... seq = itertools.chain.from_iterable(
... itertools.combinations(range(length), i)
... for i in range(2, length + 1))
... for t in seq:
... if sum(nums[i] for i in t) == target:
... out.append(t)
... return out
...
>>> find_all([2, 6, 11, 15], 19)
[(0, 1, 2)]
>>>
>>> find_all([2, 2, 2, 2], 4)
[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]
>>>
>>> find_all([2, 2, 2, 2], 6)
[(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)]
>>>
>>> find_all([2, 6, 11, 15], 17)
[(0, 3), (1, 2)]
>>>
У тебя один кусок кода связан с другим куском кода (связан - значит, зависит от него; если первый убрать, то второй полностью развалится).
Я же отвязал эти куски друг от друга и благодаря этому оно теперь готово к дальнейшему выделению функций.
Пример
>>> import itertools
>>>
>>> def find_all(nums, target):
... seq = func1(nums, len(nums))
... out = func2(nums, seq, target)
... return out
...
>>> def func1(seq, length):
... out = itertools.chain.from_iterable(
... itertools.combinations(range(length), i)
... for i in range(2, length + 1))
... return out
...
>>> def func2(lst, seq, num):
... out = []
... for t in seq:
... if sum(lst[i] for i in t) == num:
... out.append(t)
... return out
...
>>> find_all([2, 6, 11, 15], 19)
[(0, 1, 2)]
>>>
>>> find_all([2, 2, 2, 2], 4)
[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]
>>>
>>> find_all([2, 2, 2, 2], 6)
[(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)]
>>>
>>> find_all([2, 6, 11, 15], 17)
[(0, 3), (1, 2)]
>>>
func2() не знает, как собирались элементы в func1().
func2() не знает про существование func1().