递归令人困惑的操作顺序

时间:2018-01-06 07:38:14

标签: python recursion

在这段代码中

def maxVal(toConsider, avail):
if toConsider == [] or avail == 0:  
    result = (0, ())

elif toConsider[0].getCost() > avail:  
    result = maxVal(toConsider[1:], avail)  

else:  
    nextItem = toConsider[0] 
    withVal, withToTake = maxVal(toConsider[1:],
                                 avail - nextItem.getCost())
    withVal += nextItem.getValue()  
    withoutVal, withoutToTake = maxVal(toConsider[1:], avail)

    if withVal > withoutVal:
        result = (withVal, withToTake + (nextItem,))
    else:
        result = (withoutVal, withoutToTake)
return result

withVal怎么不是某种无限循环,因为它从函数中获取了它的变量,这意味着它在没有第一个变量的情况下再次重复,所以它不应该继续进行?直到有效率达到0,然后它也被添加到' nextItem'这让我头脑发热。

所以我知道

withVal, withToTake = maxVal(toConsider[1:],
                             avail - nextItem.getCost())

之前

withVal += nextItem.getValue()

并且没有无限循环,所以我的问题是,如果第一个例子证明它再次回忆起这个函数,那么它是如何使用2个赋值保持秩序的呢?

1 个答案:

答案 0 :(得分:0)

由于avail == 0不是唯一的停止条件,因此保证此功能终止。拥有toConsider == []也足够了。当你调用代码时

withVal, withToTake = maxVal(toConsider[1:],
                             avail - nextItem.getCost())

特别注意代码段[1:]。这表示您只传递了toConsider列表的大部分内容。它每次变小1,最终它的长度将达到0.由于递归最终结束,你终于可以进入下一个作业withVal += nextItem.getValue()

有时候,使用pythontutor.com可以更容易地找到这样的问题的底部,这使您可以逐步浏览并可视化代码,并查看哪些值以哪种顺序变化。我并不隶属于他们,但是对于像这样的小问题他们有一个好的产品。