我是 python 的新手,正在尝试解决我的家庭作业...我正在尝试创建一个递归函数,该函数采用数字列表 [a、b、c ....] 并将其转换为该列表: [a, a+b, a+b+c, ....].
这是我的代码:
def rec_cumsum(numbers):
''' Input: numbers - a list of numbers,
Output: a list of cumulative sums of the numbers'''
new_list=numbers
last=new_list[-1]
if numbers==[]:
return numbers
if len(numbers) == 1:
return numbers[0]
new_list.remove(last)
rec= rec_cumsum(new_list)
new_list.append(rec+last)
return last+rec
这行得通,但是因为我对 last+rec 使用了 return,所以我不能使用 return 来取回列表 (new_list)。请向我解释我做错了什么...谢谢!
请您参考如下方法:
让我们编写一些测试用例并练习一些测试驱动开发:
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))
如果我们将此添加到您的代码中并且 run it, we get :
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
现在再次运行测试。 This time we get
return last+rec
TypeError: unsupported operand type(s) for +: 'int' and 'list'
所以现在 Python 说 last 是一个 int 而 rec 是一个 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) 有关。此命令从 new_list 中删除 first 出现的 last。我们要删除最后 出现的地方。
因此,让我们使用
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
Run the tests .有用!现在回顾我们的解决方案并了解如何将其收紧并使其更加优雅是一个很好的做法。 我看到我们使用了 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
