问题
I have a deeply nested dict and need to iterate through it and return the value corresponding to the key
argument, second argument of my function.
For example, with
tree = {"a": 12, "g":{ "b": 2, "c": 4}, "d":5}
tree_traverse(tree, "d")
should return 5
Here is my code:
def tree_traverse(tree, key):
for k,v in tree.items():
if isinstance(v, dict):
tree_traverse(v, key)
elif k == key:
return v
The problem I have is that this function returns None if it doesnt find the matching key once it's done iterating through the deepest nested dict. I don't want it to return anything before the matching key is found.
I didn't find a solution in another thread, most of them use print statements and don't return anything so I guess it avoids this issue.
回答1:
You have to check whether the recursive call actually found something so you can continue the loop. E.g. try the following:
def tree_traverse(tree, key):
for k, v in tree.items():
if k == key:
return v
elif isinstance(v, dict):
found = tree_traverse(v, key)
if found is not None: # check if recursive call found it
return found
回答2:
Here we instantiate an object when the function is created, that all executions of the function will share, called _marker
. We return this object if we don't find the key. (You could also use None
here, but None
is frequently a meaningful value.)
def tree_traverse(tree, key, *, _marker=object()):
for k,v in tree.items():
if isinstance(v, dict):
res = tree_traverse(v, key, _marker=_marker)
if res is not _marker:
return res
elif k == key:
return v
return _marker
def find(tree, key):
_marker = object()
res = tree_traverse(tree, key, _marker=_marker)
if res is _marker:
raise KeyError("Key {} not found".format(key))
return res
I use tree_traverse
as a helper function because we want different behaviour at the outermost layer of our recursion (throw an error) than we want inside (return a _marker
object)
来源:https://stackoverflow.com/questions/52260624/recursively-iterate-through-a-nested-dict-and-return-value-of-the-first-matching