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