简体   繁体   English

在递归中使用变量迭代二叉树时出错(Python)

[英]Error when using a variable in recursion to iterate through a binary tree (Python)

def berry_finder(t):
    """Returns True if t contains a node with the value 'berry' and 
    False otherwise.

    >>> scrat = tree('berry')
    >>> berry_finder(scrat)
    True
    >>> sproul = tree('roots', [tree('branch1', [tree('leaf'), tree('berry')]), tree('branch2')])
    >>> berry_finder(sproul)
    True
    """
    if is_leaf(t):
        if label(t)=='berry':
            return True
        else :
            return False    
    else:
        if label(t)=='berry':
            return True
        else:
            for branch in branches(t):
                branch_list=[]
                branch_list+=[berry_finder(branch)]                         
            if True in branch_list:
                return True
            else:
                return False

This is the wrong code I wrote.And the function's purpose is to find if any node's value is 'berry'.这是我写的错误代码。该函数的目的是查找是否有任何节点的值是“浆果”。

The wrong part of the code is the recursion part(ie the code under the second else )代码的错误部分是递归部分(即第二个else下的代码)

But I think my solution is right.I create a branch_list to store all boolean value of the branches,and if any value in branch_list is True ,then return True .但我认为我的解决方案是正确的。我创建了一个branch_list来存储分支的所有 boolean 值,如果branch_list中的任何值为True ,则返回True

I wonder whethet it is the problem of the using of branch_list ,because the branch_list may change during the different depth of recursion?我想知道是否是使用branch_list的问题,因为branch_list可能会在不同的递归深度期间发生变化?

The problem is that you reset branch_list in each iteration of the loop, so losing the previous boolean results, and ending up with only the last result.问题是您在循环的每次迭代中都重置branch_list ,因此丢失了之前的 boolean 结果,最终只得到最后一个结果。

You need to move that out of the loop, like so (but read on to reduce the code further -- step by step):您需要将其移出循环,就像这样(但请继续阅读以进一步减少代码 - 逐步):

        branch_list=[]
        for branch in branches(t):
            branch_list+=[berry_finder(branch)]

Not a problem, but it is more natural to use append here:没问题,不过这里用append比较自然:

        branch_list=[]
        for branch in branches(t):
            branch_list.append(berry_finder(branch))

And more pythonic is to build the list in one go through map :更多的 pythonic 是在 go 到map中构建列表:

        branch_list = list(map(berry_finder, branches(t)))

or comprehension:或理解:

        branch_list = [berry_finder(branch) for branch in branches(t)]

But you don't actually need to collect the booleans in a list at all.但是您实际上根本不需要在列表中收集布尔值。 Just use any :只需使用any

  return any(map(berry_finder, branches(t)))

The whole function can be reduced to just this:整个 function 可以简化为:

def berry_finder(t):
    return label(t)=='berry' or any(map(berry_finder, branches(t)))

You alread get answer how to use it with list您已经获得了如何将其与列表一起使用的答案

... but you don't need list for this because you can return True directly when berry_finder(branch) gives first True , and you can return False when you exit loop. ...但是您不需要 list 因为您可以在berry_finder(branch)给出第一个True True并且可以在退出循环时返回False

else:
    for branch in branches(t):
        if berry_finder(branch):  # 
            return True
    
    # --- after loop ---
    
    return False

BTW:顺便提一句:

Instead of代替

    if True in branch_list:
        return True
    else:
        return False

you can use shorter你可以用更短的

    return (True in branch_list)   # you can even skip `()`

because ... in... gives True or False因为... in...给出TrueFalse

Similar相似的

    return (label(t) == 'berry')   # you can even skip `()`

And you would replace results你会替换结果

    if True in branch_list:
        return False
    else:
        return True

you can use shorter你可以用更短的

    return not (True in branch_list)

or或者

    return (True not in branch_list)

but it is not the same as return (False in branch_list)但它与return (False in branch_list)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM