【问题标题】:recursion working in python code to find max递归在python代码中工作以找到最大值
【发布时间】:2019-03-11 04:10:14
【问题描述】:

我是递归概念的新手,试图弄清楚以下代码是如何工作的

def Max(list):
    if len(list) == 1:
        return list[0]
    else:
        m = Max(list[1:])
        return m if m > list[0] else list[0]

def main():
    list = eval(raw_input(" please enter a list of numbers: "))
    print("the largest number is: ", Max(list))


    main()

我在看代码的时候有以下疑惑

1) 切片在此处如何工作,而没有给出切片应该在 [0:9] 结束的位置(以这种方式,列表是如何被切片的)

2) **return m if m > list[0] else list[0]**statement 什么时候会被调用(我想它不会被调用,因为在 return 之前我们将多次调用函数次)

【问题讨论】:

    标签: python list recursion


    【解决方案1】:

    欢迎来到递归——它很难理解,但它有一种奇怪的优雅/美丽。

    通过一个例子来思考这个问题通常会帮助我。

    让我们假设这个列表:1, 2, 3

    我们将运行Max([1,2,3])

    1. 列表的长度是3,所以我们跳转到else部分
    2. 我们运行Max([2,3])并将结果保存到m(递归#1)
      1. [2,3]的长度是!= 0,我们去else
      2. 我们运行Max([3])并将结果保存到m(递归#2)
        1. [3] 的长度为 == 1
        2. 我们返回索引 0,即 3(递归结束 #2)
      3. 对于m,我们得到3 的值
      4. 现在我们得到声明return m if m > list[0] else list[0]
      5. 回顾:m = 3 和 list=[2,3]
      6. m > list[0] 所以我们返回 m=3(递归结束 #1)
    3. 再次回顾:m=3 和 list=[1,2,3]
    4. m > list[0] 所以我们返回m=3

    Max([1,2,3]) 的结果是3。

    请注意,代码中对Max 的每次调用都会为m 和list 创建“new” 变量,这些变量仅在该函数内部可见。内部Max 不知道外部Max 的m 和list,反之亦然。

    调用流程如下所示:

    +----------------+
    |   Max([1,2,3]  | +----+
    +------^---------+      | Step 1
           |                |
    Step 4 |       +--------v------+
           +-------+   Max([2,3])  +---+
       return 3    +---^-----------+   | Step 2
                       |               |
               Step 3  |     +---------v-----+
                       +-----+   Max([3])    |
                 return 3    +---------------+
    

    至地址 1):

    当我们使用 [n:] 进行切片时,这意味着:从索引 n 开始并获取列表的其余部分。

    至地址 2):

    我们退出递归后,看上面的例子。


    进一步阅读


    根据您的评论进行编辑

    为了帮助你理解return m if m > list[0] else list[0]这行代码,我建议你试着在心理上跟踪递归调用之前和递归调用之后的状态。

    Max 实现的想法是这样的:递归地转到列表中的最后一个元素,然后将其与倒数第二个元素进行检查,如果最后一个较大则保留该元素,否则保留第二个元素- 到最后。

    如果您的列表看起来像这样 [1,6,3,5,4,2],递归级别将返回:

    括号中的第一个数字是m,第二个是list[0]的值

    • 2(不适用,2)
    • 4 (2, 4)
    • 5 (4, 5)
    • 5 (5, 3)
    • 6 (5, 6)
    • 6 (6, 1)

    函数最终从列表的末尾开始,将最后一个值作为初始值并移动到开头,同时始终保持较大的值,从而返回最大值。

    (这很难写,希望你能理解)

    【讨论】:

    • 感谢您的精彩解释和工作,但是列表值的存储方式(例如 [2,3,] 和 1,2,3 我认为代码将在函数调用结束后终止finshed)是否创建任何内存空间(如果它创建任何内存空间,它何时会知道清除内存空间,例如它会在很长时间内存储列表)
    • 对Max 的每次调用都会创建新 变量,这些变量称为m 和list,它们存在于该调用的范围内。所以“内部”Max 不知道“外部”Max 的值,反之亦然。
    • 所以最后我想最后一次执行的结果将结果传递给最后一次执行以这种方式执行(如果我错了,请纠正我)
    • 非常感谢您的耐心和解释
    • 不确定是否理解你的想法,但我试图在上面形象化它。把它想象成打开一个俄罗斯娃娃然后合上。
    【解决方案2】:
    1. 这是一种正常的切片方式。 [1:] 表示从第一个元素到结尾。
    2. 函数是递归的。所以如果你有一个元素列表[4,3],它

    1) 两次获取 if 语句的 else 分支,将 [4,3][1:] 计算为 [3] 并调用 Max([3]))。

    2) 递归第二阶段的列表长度为 1,因此它采用 if 语句的第一个分支并返回 3 作为元素。

    3) 我们回到第一次调用,我们将第一个元素 list[0]=4 与结果 m=3 进行比较,并将它们中的较大者作为返回值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-18
      • 2021-12-08
      • 2016-06-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多