为什么我需要两个条件分支才能使用rreverse函数?

时间:2018-09-25 11:39:08

标签: python python-3.x recursion

我进行了一次练习,尝试使用在另一个人的问题上找到的部分代码,但是我发现我需要不知道为什么要做的一部分代码。

我用于功能的完整代码是这样的:

def rreverse(s):
    if s == "":
        return s
    else:
        return rreverse(s[1:]) + s[0]

但是我只使用else作为语句,但没有得到我想要的结果。

def recur_reverse(x):
    if x != "":
        return recur_reverse(x[1:]) + x[0]

我收到TypeError的提示:“ +不支持的操作数类型:'NoneType'和'str'。”

第一个示例可以正常工作,而第二个示例在区别在于此if语句时抛出错误是什么逻辑呢?为什么我的版本不正确?

谢谢!

5 个答案:

答案 0 :(得分:6)

第二个构造的问题是,如果s是空字符串,则该函数返回不是字符串的None,并且最终调用方期望一个字符串,甚至是空的,因此返回None会使调用者的代码中断(这会导致类似Why does my function return None?的问题)

您可以使用三元表达式编写它,以确保无论x的值是什么,它都会返回某些内容

def recur_reverse(x):
    return recur_reverse(x[1:]) + x[0] if x else ""

答案 1 :(得分:5)

当Python函数到达其最后一个没有显式return语句的语句时,它隐式返回None。在第二个示例中:

def recur_reverse(x):
    if x != "":
        return recur_reverse(x[1:]) + x[0]

x实际上是空字符串时,将跳过if分支,并以“下一条语句”继续执行-但是由于没有“下一条语句”(您已到达函数的末尾) ),该函数将返回None。对于递归调用,您总是总是以空字符串调用该函数,因此该函数返回None,并且如错误消息所述,您无法将None与字符串连接(出于非常明显的原因) )。

答案 2 :(得分:4)

在递归中,您每次“ pop ”从字符串s[0]中的第一个元素s起,然后将其附加到其余元素{{ 1}}。

但这意味着我们最终将使用空字符串进行呼叫(因为字符串具有固定的长度,并且如果每次弹出一个字符,最终我们都会用尽所有字符)。

一个空字符串的首个字符为{em> no ,因此会产生一个rreverse(s[1:]),以防止我们将其作为基本情况空字符串:空字符串的相反是空字符串。所以:

s[0]

如果您不执行 这种情况,则存在一个没有 explicit 返回表达式的代码路径。如果某个函数未明确返回某些内容,则Python将改为返回IndexError

但是请注意,我们进行了def rreverse(s): if s == "": # empty string (base case) return s else: # non-empty string (recursive case) return rreverse(s[1:]) + s[0]个调用,如果返回的是None,则我们将rreverse(s[1:])和一个字符串(例如None)加在一起。但这没有任何意义:Python不知道如何添加None和字符串(这样做是没有意义的),因此会出错。

例如,您的版本将为'a'进行如下调用(无效的Python,仅用于演示问题):

None

第一个版本:

rreverse('ab')

答案 3 :(得分:3)

因为您未指定x = ""时发生的情况。如果x确实是一个空字符串,则会导致错误,因为您的函数将返回类型None,这是调用者无法预料的。

答案 4 :(得分:0)

对于< ng-container [matColumnDef]="col" *ngFor="let col of displayedColumns" > < mat-header-cell *matHeaderCellDef> {{ col }} < /mat-header-cell> < mat-cell *matCellDef="let element">{{ element[col] }} < /mat-cell> < /ng-container> 以外的其他情况,第二个不返回任何内容,因此当您执行x != ""时可能不返回任何内容(无)