The documentation string you provided at the top of the module would better be placed in the function, and the examples should be formatted as doctests so that they can automatically be checked.
The control flow can be simplified and manual handling of indexes eliminated if you iterate directly over the input list, maintain a deque
for the currently considered subsequence, and use an inner while
loop for discarding numbers.
from collections import deque
def sum_targetcontains_subsequence_sum(numbers, target):
'''Given a sequence of positive integers `numbers` and an integer `target`,
return whether there is a continuous sub-sequence of `numbers` that sums up
to exactly `target`.
>>> sum_targetcontains_subsequence_sum([23, 5, 4, 7, 2, 11], 20) # 7 + 2 + 11 = 20
True
>>> sum_targetcontains_subsequence_sum([1, 3, 5, 23, 2], 8) # 3 + 5 = 8
True
>>> sum_targetcontains_subsequence_sum([1, 3, 5, 23, 2], 7)
False
'''
subsequence = deque()
current_sumtotal = 0
for number in numbers:
if current_sumtotal < target:
subsequence.append(number)
current_sumtotal += number
while current_sumtotal > target and subsequence:
current_sumtotal -= subsequence.popleft()
if current_sumtotal == target:
return True
return False
The original name sum_target
suggests that the function returns a number when it actually returns a boolean value (it is a predicate). Such functions tend to have names like "has", "is", "contains", etc. While I'm still not quite happy with it, the name contains_subsequence_sum
is a better fit.