在询问之前,我搜索了一些旧问题并且更好地将“返回”放在内部重新调用函数以获得预期结果。 其中一些人喜欢: How to stop python recursion Python recursion and return statements。但是当我对我的问题做同样的事情时,它会变得更糟。
我有一个二进制搜索树,并希望通过给定一个节点的键来获取TreeNode实例,因此它看起来更容易遍历,我已经很容易实现下面的类似函数,我没有把它放在函数前面:
def getNode(treeNode,key):
if(treeNode):
if(treeNode.key==key):
print("got it=",treeNode.key)
return treeNode
else:
return getNode(treeNode.left_child(),key)
return getNode(treeNode.right_child(),key)
所以对于我的新要求,我首先将其组成如下:
{{1}}
然后问题出现了,它找到了键/节点但是一直运行并最终报告一个None错误,然后我把返回放在左右两个分支的前面,如下所示:
{{1}}
但是这会让事情变得更糟,它确实达到了找到的密钥并且更早地返回。
然后我尝试删除分支的一个“返回”,无论是右还是左。它工作(更新:当我的测试用例只包含3个节点,当我放置更多节点,它没有工作,或者说预期节点是否来自右边,然后在右分支调用工作前面返回时,这有用)对于左边一个,它没有)。什么是更好的解决方案?
答案 0 :(得分:1)
您需要return
递归通话的结果,但您并不总是无条件地这样做。有时你不会从第一次递归中得到你需要的结果,所以你需要在返回任何东西之前递归另一个。
处理此问题的最佳方法通常是将递归的结果分配给变量,然后可以对其进行测试。因此,如果getNode
返回一个节点(如果找到了密钥),或None
(如果它没有),则可以执行以下操作:
result = getNode(treeNode.left_child(),key)
if result is not None:
return result
return getNode(treeNode.right_child(),key)
在这种特定情况下,由于None
是假的,您可以使用or
运算符执行"短路"为你:
return getNode(treeNode.left_child(),key) or getNode(treeNode.right_child(),key)
只有在第一个返回假名值(例如None
)时才会进行第二次递归调用。
请注意,对于某些递归算法,您可能需要无条件地多次递归,然后在返回结果之前将结果组合在一起。例如,在树中添加(数字)键值的函数可能如下所示:
def sum_keys(node):
if node is None: # base case
return 0
left_sum = sumKeys(node.left_child()) # first recursion
right_sum = sumKeys(node.right_child()) # second recursion
return left_sum + right_sum + node.key # add recursive results to our key and return
答案 1 :(得分:0)
而不是(defn map-invert+ [kfn vfn data]
(reduce (fn [acc entry] (assoc acc (kfn entry) (vfn entry)))
{} data))
user> (def data
{1 ["bar" "choco"]
2 ["some" "thing"]})
#'user/data
user> (def inverted (map-invert+ (comp first val) key data))
#'user/inverted
user> inverted
;;=> {"bar" 1, "some" 2}
user> (inverted "bar")
;;=> 1
,请使用return
:
yield
输出:
class Tree:
def __init__(self, **kwargs):
self.__dict__ = {i:kwargs.get(i) for i in ['left', 'key', 'right']}
t = Tree(key=10, right=Tree(key=20, left=Tree(key=18)), left=Tree(key=5))
def find_val(tree, target):
if tree.key == target:
yield target
print('found')
else:
if getattr(tree, 'left', None) is not None:
yield from find_val(tree.left, target)
if getattr(tree, 'right', None) is not None:
yield from find_val(tree.right, target)
print(list(find_val(t, 18)))
但是,您也可以通过实现found
[18]
方法将get_node
函数实现为二叉树类中的方法:
__contains__
输出:
class Tree:
def __init__(self, **kwargs):
self.__dict__ = {i:kwargs.get(i) for i in ['left', 'key', 'right']}
def __contains__(self, _val):
if self.key == _val:
return True
_l, _r = self.left, self.right
return _val in [[], _l][bool(_l)] or _val in [[], _r][bool(_r)]
t = Tree(key=10, right=Tree(key=20, left=Tree(key=18)), left=Tree(key=5))
print({i:i in t for i in [10, 14, 18]})
答案 2 :(得分:0)
不了解您的对象:
三个基本案例:
None
- >返回无如果不是基础案例递归。使用or
短接递归:如果匹配则返回左分支或返回正确的分支结果(也可能是None)
def getNode(treeNode,key):
if treeNode == None:
return None
elif treeNode.key == key:
print("got it=",treeNode.key)
return treeNode
elif not any(treeNode.has_left_child(), treeNode.has_right_child()):
return None
#left_branch = getNode(treeNode.left_child(),key)
#right_branch = getNode(treeNode.right_child(),key)
#return left_branch or right_branch
return getNode(treeNode.left_child(),key) or getNode(treeNode.right_child(),key)