让我们编写一些测试用例并实践一些测试驱动的开发:
tests = [[], # Desired answer: []
[1], # [1]
[1,2], # [1, 3]
[1,2,3], # [1, 3, 6]
[1,2,1,3]] # [1, 3, 4, 7]
for t in tests:
print(rec_cumsum(t))
如果我们将其添加到您的代码中并运行它,我们会得到:
last=new_list[-1]
IndexError: list index out of range
为什么是这样?显然 -1 是一个超出范围的索引。为什么没有new_list-1索引?
啊哈。如果new_list为空,就会发生这种情况。所以我们需要首先解决基本情况。当我们这样做的时候,让我们也使用@MartijnPieters 的建议:
if len(numbers) <= 1:
return numbers
获得
def rec_cumsum(numbers):
''' Input: numbers - a list of numbers,
Output: a list of cumulative sums of the numbers'''
if len(numbers) <= 1:
return numbers
new_list=numbers
last=new_list[-1]
new_list.remove(last)
rec = rec_cumsum(new_list)
new_list.append(rec[-1]+last)
return last+rec
现在再次运行测试。这次我们得到
return last+rec
TypeError: unsupported operand type(s) for +: 'int' and 'list'
所以现在 Python 说lastis anint和recis a list,我们不能把两者加在一起。
好的,rec应该是一个列表,因为它是rec_cumsum(new_list). 应该换last+rec什么?
让我们考虑一个具体的例子。如果rec是,[a, a+b]那么我们要返回[a, a+b, a+b+c]。我们如何形成a+b+c?
如何将最后一个元素添加到最后rec一个元素numbers:
rec[-1]+last
我们想将其附加到末尾rec:
rec.append(rec[-1]+last)
让我们做出改变,看看会发生什么。但是在我们编辑的同时,让我们也清理一些我们从未使用过的代码。我们可以删除new_list.append(rec[-1]+last):
def rec_cumsum(numbers):
''' Input: numbers - a list of numbers,
Output: a list of cumulative sums of the numbers'''
if len(numbers) <= 1:
return numbers
new_list=numbers
last=new_list[-1]
new_list.remove(last)
rec = rec_cumsum(new_list)
rec.append(rec[-1]+last)
return rec
现在我们的程序返回
[]
[1]
[1, 3]
[1, 3, 6]
[2, 3, 4, 7]
万岁,我们的程序运行没有错误。但是等等......它返回错误的结果。看最后一行。
rec_cumsum([1,2,1,3])正在返回[2,3,4,7],而正确答案是[1,3,4,7]。为什么第一个数字是错误的?
它与new_list.remove(last). 此命令删除第一次出现的lastfrom new_list。我们要删除最后一次出现。
所以相反,让我们使用
new_list = numbers[:-1]
所以程序变成了:
def rec_cumsum(numbers):
''' Input: numbers - a list of numbers,
Output: a list of cumulative sums of the numbers'''
if len(numbers) <= 1:
return numbers
new_list=numbers[:-1]
last=numbers[-1]
rec = rec_cumsum(new_list)
rec.append(rec[-1]+last)
return rec
运行测试。有用!现在回顾一下我们的解决方案,看看如何将其收紧并变得更优雅,这是一个很好的做法。我看到我们使用new_list和last作为临时变量。我们真的需要它们吗?
def rec_cumsum(numbers):
if len(numbers)<=1:
return numbers
result = rec_cumsum(numbers[:-1])
result.append(result[-1]+numbers[-1])
return result