【问题标题】:recursion of the form var += func(var, n-1)var += func(var, n-1) 形式的递归
【发布时间】:2016-10-03 11:48:32
【问题描述】:

TL/DR 您如何评估var += func(var, n-1) 形式的语句?

编辑:“评估”是指,该语句右侧调用的值是如何确定的。在下面给出的函数中,var += func(var, n-1) 总是产生sum += sum。但是为什么总是调用sum?为什么不sum += (n-1)?是什么决定了右侧调用哪个值?在一些回复的帮助下,我想我已经弄清楚了(见下文),但对这个主题的更多了解将始终受到赞赏。我才刚学几天编程。

asked a question regarding a recursive function 收到了一个我很满意的答案,但又提出了几个问题。我一直在查看有关该主题的先前问题,但我仍然缺少一些东西。感觉递归是一个基本概念,必须完全掌握才能成功编程,所以我想一直问问题,直到我弄明白为止。回答者提供了另一个示例函数供我考虑:

def foo(sum, n):
    if (n == 0):
        return sum
    sum += foo(sum, n-1)
    sum /= 2
    return foo(sum, n-1)

我从未见过 += 与具有多个参数的函数一起使用,我不知道如何评估它。我在sum += foo(sum, n-1)sum /= 2 之后添加了print(sum),试图看看发生了什么。运行 foo(10, 3) 导致:

20
10.0
20.0
10.0
20.0
10.0
20.0
10.0
20.0
10.0
20.0
10.0
20.0
10.0

我决定将+= 更改为*=,看看这是否会使发生的事情更清楚。这是那个程序:

def foo(sum, n):
    if (n == 0):
        return sum
    sum *= foo(sum, n-1)
    print(sum)
    sum /= 2
    print(sum)
    return foo(sum, n-1)

foo(10, 3)

它产生了以下内容:

100
50.0
500.0
250.0
62500.0
31250.0
312500.0
156250.0
24414062500.0
12207031250.0
1907348632812500.0
953674316406250.0
9.094947017729283e+29
4.5474735088646414e+29

我可以在这个输出中追踪一些不同的交织模式,(即在第 1、第 2 和第 4 个实例中调用原始总和 10;输出分为两个递归、两个递归和三个递归的组;输出sum/2 提供第 3、5 和第 7 个实例的输入),但我似乎无法在不知道如何评估 sum *= foo(sum, n-1) 或原始 sum += foo(sum, n-1) 的情况下解开它。

【问题讨论】:

  • 您需要更具体地提出您的问题 - “评估”该行的问题究竟是什么?首先调用该函数并将其结果添加到本地值sum
  • += 和递归没有什么特别之处。您在右侧有一个表达式,它被评估然后添加到左侧的对象中。递归调用在那里没有什么不同。对于不可变类型,x += yx = x + y 完全相同。
  • 抱歉,如果我根本不知道如何正确地提出这个问题。这一切我都知道。关于评估,foo(sum, n-1) 中有两个参数。这是如何添加到sum 的? sum 中添加了什么?我从输出中收集到只有sum 参数被添加到sum,这导致了第二个问题:语句sum += foo(sum, n-1) 是否调用foo(sum, n) 的另一个实例,如果是,为什么函数在n == 0 完全耗尽n 并调用return 之前传递给sum/2

标签: python python-3.x recursion


【解决方案1】:

在 python 中,x += yx = x + y 相同,即将 y 添加到 x 的值并保存到 x

在您的情况下,sum += foo(sum, n-1) 表示foo(sum, n-1) 返回的值与sum 相加,并将其保存为sum

*=-= 等也同样如此。例如:x *= y 表示 将 y 与 x 相乘并保存为 x。希望能回答你的问题。

阅读:Augmented Assignment Statements 了解更多信息。

【讨论】:

  • x += y 与 x = x + y 相同:仅适用于不可变类型。对于可变类型,存在就地更改对象的选项。因此对于列表,+=list.extend() 相同,后跟重新绑定名称。
  • 感谢您的回复。我的问题是:具有多个参数的函数返回的值的性质是什么,允许将其添加到单个变量中?这种形式是否仅在左侧的变量也是右侧的参数之一时才有效? mus += foo(sum, n-1) 的输出是什么?还有一个后续问题:在上面的函数中,语句sum += foo(sum, n-1) 是否调用了foo(sum, n) 的另一个实例,如果是,为什么函数在n 完全耗尽n == 0 之前传递给sum/2并调用返回?
【解决方案2】:

虽然我还没有弄清楚给定函数产生输出的确切原因,但我终于弄清楚了该主题的主要问题,即如何评估 var += func(var, n-1) 形式的语句。

虽然x += y 形式的语句很容易理解,但该语句右侧的函数有多个参数。我无法理解的是要使用来自func(var, n-1) 的哪个值以及如何确定它。所以我做了实验。我在函数中添加了一个新的第一条语句mus = 3,并将sum += foo(sum, n-1) 替换为mus += foo(sum, n-1) 并打印了结果。我颠倒了函数中的参数位置并检查了结果。我在函数中添加了第三个参数并检查了它。每次,sum 的值都会在 sum += foo(sum, n-1) 的每个变体中被调用。

然后我从return sum 中删除sum 并运行它,它产生了一个TypeError 然后它点击了。所以我把它改成了return n-1,然后就变成了sum += foo(sum, n-1)中调用的值。我将它更改为我添加的新第三个变量return x,然后就是调用的值。

看来,为了评估var += func(var, n-1) 形式的语句,您必须检查函数运行时在基本情况下返回的参数。如有错误请指正~

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    • 2014-05-03
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    • 2014-06-20
    • 2018-08-18
    相关资源
    最近更新 更多