Hil*_*ani 5 python recursion python-3.x
我做了一个练习,试图在另一个人的问题上使用我在这里找到的代码部分,但我发现我需要一部分代码,我不知道为什么要这样做.
我用于我的函数的完整代码是这样的:
def rreverse(s):
if s == "":
return s
else:
return rreverse(s[1:]) + s[0]
Run Code Online (Sandbox Code Playgroud)
但是我只使用了else作为声明,而我没有得到我希望得到的结果.
def recur_reverse(x):
if x != "":
return recur_reverse(x[1:]) + x[0]
Run Code Online (Sandbox Code Playgroud)
我得到TypeError说"不支持的操作数类型为+:'NoneType'和'str'."
第一个例子正常工作的逻辑是什么,第二个例子在这个if语句的差异时抛出错误是什么?为什么我的版本不正确?
谢谢!
第二个结构的问题是if s是空字符串,函数返回None的不是字符串,而end-caller 需要一个字符串,甚至是空的,所以返回None会使调用者代码中断(这导致像为什么我的函数返回None?)
你可以用三元表达式来编写它,以确保它返回任何值的值 x
def recur_reverse(x):
return recur_reverse(x[1:]) + x[0] if x else ""
Run Code Online (Sandbox Code Playgroud)
当Python函数在没有显式return语句的情况下到达它的最后一个语句时,它会隐含地返回None.在你的第二个例子中:
def recur_reverse(x):
if x != "":
return recur_reverse(x[1:]) + x[0]
Run Code Online (Sandbox Code Playgroud)
当x实际上是空字符串时,if跳过分支并继续执行"下一个语句" - 但由于没有"下一个语句"(你已到达函数的结尾),函数返回None.使用递归调用,您总是最终使用空字符串调用该函数,因此该函数返回None,并且如错误消息所示,您不能None与字符串连接(出于非常明显的原因).
在递归中,您每次从字符串中“弹出”第一个元素,并将其附加到其余元素的相反位置。s[0]srreverse(s[1:])
但这意味着我们最终将使用空字符串进行调用(因为字符串具有固定的长度,如果我们每次弹出一个字符,最终我们将用完字符)。
空字符串没有第一个字符s[0],因此这将引发IndexError,以防止我们将空字符串实现为基本情况:空字符串的反向是空字符串。所以:
def rreverse(s):
if s == "": # empty string (base case)
return s
else: # non-empty string (recursive case)
return rreverse(s[1:]) + s[0]Run Code Online (Sandbox Code Playgroud)
如果您不实现这种情况,则存在一个没有显式返回表达式的代码路径。如果函数没有显式返回某些内容,Python 将返回None。
但请注意,我们进行rreverse(s[1:])调用,如果返回 in None,我们将因此将None和 一个字符串(例如'a')添加在一起。但这没有意义:Python 不知道如何添加 aNone和字符串(好吧,这样做没有意义),因此会出现错误。
因此,您的版本将用于rreverse('ab')像这样的调用(不是有效的Python,只是为了演示问题):
# second version
rreverse('ab')
-> rreverse('b') + 'a'
-> rreverse('') + 'b'
-> None
None + 'a' ==> TypeError
Run Code Online (Sandbox Code Playgroud)
而对于第一个版本:
# first version
rreverse('ab')
-> rreverse('b') + 'a'
-> rreverse('') + 'b'
-> ''
'' + 'b'
'b'
'b' + 'a'
'ba'
Run Code Online (Sandbox Code Playgroud)