我正在尝试理解递归。这是关于在Python中实现BST的查找功能的一个非常基本的问题。此代码直接取自此post。
在此示例中,lookup函数返回两个值:(1)树中是否存在该值;(2)如果在树中找到该值,则该值的父节点是什么。
为什么你需要做“return self.left.lookup(data,self)”?为什么你不能在没有返回的情况下做“self.left.lookup(data,self)”?
class Node:
...
def lookup(self, data, parent=None):
"""
Lookup node containing data
@param data node data object to look up
@param parent node's parent
@returns node and node's parent if found or None, None
"""
if data < self.data:
if self.left is None:
return None, None
return self.left.lookup(data, self)
elif data > self.data:
if self.right is None:
return None, None
return self.right.lookup(data, self)
else:
return self, parent
我已经实现了一个查找的工作版本,它不会返回下面的值的父节点。以下工作正常,无需返回self.left.lookup():
def lookup(self, value):
if(self.value == value):
print("Found value!")
return True
elif self.value > value:
if self.left == None:
print("Value not found.")
return False
else:
self.left.lookup(value)
else:
if self.right == None:
print("Value not found.")
return False
else:
self.right.lookup(value)
在下面的代码中,我尝试返回一个布尔值,表示值是否在树中以及父节点(就像原始帖子那样):
def lookup(self, value, parent=None):
if(self.value == value):
print("Found value!")
return True, parent
elif self.value > value:
if self.left == None:
print("Value not found.")
return False, None
else:
self.left.lookup(value, self)
else:
if self.right == None:
print("Value not found.")
return False, None
else:
self.right.lookup(value, self)
上面的代码不起作用,我得到错误:“TypeError:'NoneType'对象不可迭代”。当我“返回self.right.lookup(value,self)”和“return self.left.lookup(value,self)”时,TypeError消失了,但我不明白为什么。为什么添加“return”修复代码?
答案 0 :(得分:0)
如果没有return语句,python会自动返回None。你可以在python shell中测试它:
>>> def sum(a, b): a + b
>>> print sum(1, 2)
None
添加return语句告诉python将计算出的值返回给调用者:
>>> def sum(a, b): return a + b
>>> print sum(1, 2)
3
在你的情况下,结果是计算结果,但是一旦结束它将被丢弃,因为中间调用 lookup 没有返回计算结果。
为了说明玩具示例发生了什么,请考虑一个简单的递归乘法函数:
>>> def mult(n, m, acc=0):
if m == 0: return acc
else:
print("m %s: %s" % (m, acc))
mult(n, m-1, acc+n)
此处对 mult 的中间调用不会返回递归步骤计算的结果。调用该函数会产生此输出:
>>> print mult(3, 3)
m 3: 0
m 2: 3
m 1: 6
None
正如您所看到的,结果是计算出来的,但是一旦最终结果准备就绪,一切都会被抛弃。
添加return语句:
>>> def mult(n, m, acc=0):
if m == 0: return acc
else:
print("m %s: %s" % (m, acc))
return mult(n, m-1, acc+n)
产生预期的产出:
print mult(3, 3)
m 3: 0
m 2: 3
m 1: 6
9
通常,递归函数的每一步必须按原样返回后续步骤的结果(尾递归)或以某种方式修改。