1

首先,这是问题和编写的代码:

def family_lineage(familytree, lineage):
    '''(dict, list of strs) -> boolean
    Return True if lineage specifies a list of names who are directly related
    in a chain of parent-child relationships, and NOT child-parent, parent-grandchild..etc,
    beginning from the first generation listed.

    >>> trace_lineage({'Gina': {'Sam': {'Tina': {}},
                           'Li': {}},
                   'Guy': {}},
                      ['Gina'])
    True

    >>> trace_lineage({'Gina': {'Sam': {'Tina': {}},
                               'Li': {}},
                       'Guy': {}},
                      ['Gina', 'Sam', 'Tina'])
    True
    >>> trace_lineage({'Gina': {'Sam': {'Tina': {}},
                               'Li': {}},
                       'Guy': {}},
                      ['Gina', 'Tina'])
    False
    '''

因此,在上面的示例中,它显示“Guy”没有孩子,“Gina”有两个孩子,“Sam”和“Li”。“山姆”有一个孩子,“蒂娜”。

for k, v in familytree.items():
    for n, m in v.items():
        if lineage[0] == any(k) and len(lineage) == 1:
            return True
        elif lineage[0] == k and lineage[1] == n and len(lineage) ==2:
            return True
        elif lineage[0] == k and lineage[1] == n and lineage[2] == m and \
        len(lineage) == 3:
            return True
        else:
            return False

所以,我的问题是,如果家谱超过三代,我将如何写这个?有没有更简洁的方法来编写这段代码?

4

2 回答 2

4

这是一种迭代方法,即使lineage不是从家族树的顶部开始也可以使用:

def family_lineage(familytree, lineage):
    trees = [familytree]
    while trees:
        tree = trees.pop()
        trees.extend(t for t in tree.values() if t)
        for name in lineage:
            if name not in tree:
                break
            tree = tree[name]
        else:
            return True
    return False
于 2013-07-22T21:24:38.233 回答
2

基本上,你想看看你是否可以遍历树;用于reduce()循环遍历元素,如果KeyError引发 a,则路径不存在:

def family_lineage(familytree, lineage):
    if not familytree:
        return False
    try:
        reduce(lambda d, k: d[k], lineage, familytree)
        return True
    except KeyError:
        # No match at this level, recurse down the family tree
        return any(family_lineage(val, lineage) for val in familytree.itervalues())

reduce()lambda函数递归地应用于lineage,从 开始familytree

KeyError为了支持在树的更深处找到谱系,您需要在s上沿树向下递归。

演示:

>>> tree = {'Gina': {'Sam': {'Tina': {}}, 'Li': {}}, 'Guy': {}}
>>> family_lineage(tree, ['Gina'])
True
>>> family_lineage(tree, ['Gina', 'Sam', 'Tina'])
True
>>> family_lineage(tree, ['Gina', 'Tina'])
False
>>> family_lineage(tree, ['Sam', 'Tina'])
True
于 2013-07-22T21:15:18.393 回答