1

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

## 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', 'S', [])
wd = ('D', 'H', [])
we = ('E', 'R', [wb])
wf = ('F', 'G', [we, wa])
wg = ('G', 'S', [wc, wd])
wh = ('H', 'G', [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

在上面的函数中,我使用非本地范围结果中的变量来存储想要的值并使递归助手不返回任何内容。


def get_same_house_as_parent(wiz):
    """Produce names of wizard which be in the same house as their parent.
    
    Args:
        wiz(tuple[str, str, list]): name, 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, '', [])

我使用了辅助函数 return 和非局部变量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, str, list]): name, 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)

    def fn_for_low(low, 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 相同方法的函数视为尾递归吗?

4

0 回答 0