[英]Python iterating through nested dictionaries
First of all, here is the question and the code written: 首先,这里是问题和编写的代码:
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
'''
So, in the above example, it shows the 'Guy' has no children, and 'Gina' has two children, 'Sam', and 'Li'. 因此,在上面的示例中,它显示“ Guy”没有孩子,而“ Gina”有两个孩子“ Sam”和“ Li”。 'Sam' has one child, '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
So, my question is, how would I write this if the familytree extended beyond three generations? 因此,我的问题是,如果家族树扩展到三代以上,我将如何写呢? Is there a more concise way of writing this code?
有没有更简洁的代码编写方式?
Here is an iterative approach that will work even if lineage
does not start at the top of the family tree: 这是一种迭代方法,即使
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
Basically, you want to see if you can traverse the tree; 基本上,您想看看是否可以遍历树。 use
reduce()
to loop over the elements and if a KeyError
is raised, the path doesn't exist: 使用
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()
applies the lambda
function recursively to lineage
, starting with familytree
. reduce()
从familytree
开始,递归地将lambda
函数应用于lineage
。
To support finding lineages deeper down the tree, you need to recurse down the tree on KeyError
s. 为了支持寻找更深层次的谱系树倒,则需要向下递归在树上
KeyError
秒。
Demo: 演示:
>>> 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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.