Python迭代嵌套字典

时间:2013-07-22 21:10:50

标签: 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, 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'。 'Sam'有一个孩子,'Tina'。

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

所以,我的问题是,如果家庭树超过三代,我将如何写这个?是否有更简洁的方式编写此代码?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

基本上,你想看看你是否可以穿越树;使用reduce()循环遍历元素,如果引发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()lambda开头递归lineage函数。

为了支持在树的下方找到谱系,您需要在familytree s上向下递归树。

演示:

KeyError