いくつかのテストケースを作成し、テスト駆動開発を実践してみましょう。
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
、2つを足し合わせることができません。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)
ます。このコマンドは、からの最初の出現を削除します。最後のオカレンスを削除したいと思います。last
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