我进行了一次练习,尝试使用在另一个人的问题上找到的部分代码,但是我发现我需要不知道为什么要做的一部分代码。
我用于功能的完整代码是这样的:
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语句时抛出错误是什么逻辑呢?为什么我的版本不正确?
谢谢!
答案 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 != ""
时可能不返回任何内容(无)