递归地迭代嵌套的dict,并返回第一个匹配键的值

时间:2018-09-10 15:01:03

标签: python-3.x dictionary recursion

我有一个深层嵌套的dict,需要遍历它,并返回与key参数(函数的第二个参数)相对应的值。

例如,使用

tree = {"a": 12, "g":{ "b": 2, "c": 4}, "d":5}

tree_traverse(tree, "d")应该返回5

这是我的代码:

def tree_traverse(tree, key):
    for k,v  in tree.items():
        if isinstance(v, dict):
            tree_traverse(v, key)

        elif k == key:
            return v

我遇到的问题是,一旦在最深层的嵌套dict中进行迭代,该函数如果找不到匹配的键,则返回None。 我不希望它在找到匹配的键之前返回任何内容。

我没有在另一个线程中找到解决方案,其中大多数使用print语句并且不返回任何内容,所以我想它避免了这个问题。

2 个答案:

答案 0 :(得分:5)

您必须检查递归调用是否确实找到了某些东西,以便您可以继续循环。例如。尝试以下操作:

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

答案 1 :(得分:1)

这里,我们在创建函数时实例化一个对象,该函数的所有执行都将共享,称为_marker。如果找不到密钥,则返回此对象。 (您也可以在此处使用None,但是None通常是一个有意义的值。)

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

我使用tree_traverse作为辅助函数是因为我们希望在递归的最外层(抛出错误)与在内部(返回_marker对象)有不同的行为