使用python nonlocal varibles来存储递归的输出VS直接返回递归

问题描述

我正在尝试设计一个函数,通过传入一些 Wizard生成与他们的父母在同一所房子里的巫师的名字,这些Wizard 聚集在一起形成了一个家谱,如中所述文档字符串。

## Data DeFinitions:
## Wizard is (name,house,children)
## - name(str) is name of the wizard.
## - house(str) is name of the house the wizard in.
## - children(listof str) is a list of the wizard's children.
wa = ('A','S',[])
wb = ('B','G',[])
wc = ('C',[])
wd = ('D','H',[])
we = ('E','R',[wb])
wf = ('F',[we,wa])
wg = ('G',[wc,wd])
wh = ('H',[wg,wf])

这些是要传递给函数的数据的一些示例。


def get_same_house(wiz):
    """Produce the names of wizards who be in the same house as their parent.

    Args:
        wiz(tuple[str,str,list]): name,house and list of children of the wizard.

    Returns:
        list: names of wizards
    """
    result = []
    def fn_for_wiz(wiz,house):
        if wiz[1] == house:
            nonlocal result
            result.append(wiz[0])
        else:
            house = wiz[1]
        fn_for_low(wiz[2],house)

    def fn_for_low(low,house):
        if not low:
            return None
        fn_for_wiz(low[0],house),fn_for_low(low[1:],house)

    fn_for_wiz(wiz,'')
    return result

在上面的函数中,我在非局部范围内使用了一个变量 result 来存储想要的值并使递归助手不返回任何内容


def get_same_house_as_parent(wiz):
    """Produce names of wizard which be in the same house as their parent.
    
    Args:
        wiz(tuple[str,house and children of a wizard.

    Returns:
        list: names of the wizards

    todo: list of wizard to traverse next contains (wizard,parent name)
    """
    result = []
    def fn_for_wiz(wiz,ph,todo):
        if wiz[1] == ph:
            nonlocal result
            result.append(wiz[0])
        todo.extend([(w,wiz[1]) for w in wiz[2]])
        return fn_for_low(todo)

    def fn_for_low(todo):
        if not todo:
            return result
        return fn_for_wiz(todo[0][0],todo[0][1],todo[1:])

    return fn_for_wiz(wiz,'',[])

这个我使用了辅助函数的返回和非局部变量result的组合。


def get_same_house_nostoring(wiz):
    """Produce the names of wizards who be in the same house as their parent.

    Args:
        wiz(tuple[str,house and list of children of the wizard.

    Returns:
        list: names of wizards
    """
    def fn_for_wiz(wiz,house):
        if wiz[1] == house:
            return [wiz[0]] + fn_for_low(wiz[2],house)
        else:
            house = wiz[1]
            return fn_for_low(wiz[2],house):
        if not low:
            return []
        return fn_for_wiz(low[0],house) + fn_for_low(low[1:],house)

    return fn_for_wiz(wiz,'')

对于这个函数,我使用 return 语句直接返回想要的值。


所以我想知道我应该使用哪一个。 我可以使用累加器结束第三个 fn 以形成尾递归以获得更好的性能。但是,对我来说,第一个和第二个函数方法要简单得多,也更容易理解或调试,这使得它们更好用,尤其是当设计函数变得更大更复杂时。 但是有什么约定吗?它们之间有什么区别?

补充问题:使用与第一个 fn 相同方法函数是否可以视为尾递归?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)