让我们编写一些测试用例并实践一些测试驱动的开发:
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 说last
is anint
和rec
is 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)
. 此命令删除第一次出现的last
from 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