Python在嵌套字典中迭代

Python在嵌套字典中迭代,python,dictionary,nested,nested-loops,Python,Dictionary,Nested,Nested Loops,首先,以下是问题和编写的代码: 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, paren

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

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

所以,我的问题是,如果家族树延续了三代,我该怎么写呢?有没有更简洁的方法来编写这段代码?

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

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从familytree开始,递归地将lambda函数应用于沿袭

为了支持在树的更深处查找谱系,您需要在keyrerrors上沿着树递归

演示:


基本上,你想看看你是否能穿过这棵树;用于在元素上循环,如果引发KeyError,则路径不存在:

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从familytree开始,递归地将lambda函数应用于沿袭

为了支持在树的更深处查找谱系,您需要在keyrerrors上沿着树递归

演示:


以下是一种迭代方法,即使血统不是从家族树的顶部开始,它也会起作用:

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

以下是一种迭代方法,即使血统不是从家族树的顶部开始,它也会起作用:

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

进行递归调用,这样它就可以使用任何深度的树。可能重复进行递归调用,这样它就可以使用任何深度的树。可能重复使用队列的好方法。非常感谢您的帮助!:你能解释一下你做了什么吗?将familytree放在方括号中,然后在以后使用pop的目的是什么?当代码中断时,是否直接返回False?trees是树中所有未访问分支的容器,因此trees=[familytree]只是为我们提供了整个树的起点。在while循环trees.pop的每次迭代中,我们将使用树的一个分支节点,该节点的所有非空子节点都将添加到树中。当代码中断时,它不会直接返回False,它只是中断for循环。for上的else子句仅在没有中断的情况下执行,因此只有在找到沿袭中的每个名称时,才会返回True。访问所有分支后,我们返回False。使用队列的方法很好。非常感谢您的帮助!:你能解释一下你做了什么吗?将familytree放在方括号中,然后在以后使用pop的目的是什么?当代码中断时,是否直接返回False?trees是树中所有未访问分支的容器,因此trees=[familytree]只是为我们提供了整个树的起点。在while循环trees.pop的每次迭代中,我们将使用树的一个分支节点,该节点的所有非空子节点都将添加到树中。当代码中断时,它不会直接返回False,它只是中断for循环。for上的else子句仅在没有中断的情况下执行,因此只有在找到沿袭中的每个名称时,才会返回True。访问所有分支后,我们返回False。感谢您的帮助!:谢谢你的帮助D