python-3.x 递归循环访问嵌套dict并返回第一个匹配键的值

ruoxqz4g  于 2023-01-06  发布在  Python
关注(0)|答案(3)|浏览(122)

我有一个嵌套很深的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语句,不返回任何东西,所以我猜它避免了这个问题。

2wnc66cl

2wnc66cl1#

你必须检查递归调用是否真的找到了一些东西,这样你才能继续循环。例如,尝试以下操作:

def tree_traverse(tree, key):
    if key in tree:
        return tree[key]
    for v in filter(dict.__instancecheck__, tree.values()):
        if (found := tree_traverse(v, key)) is not None:  
            return found
1aaf6o9v

1aaf6o9v2#

这里我们在函数创建时示例化了一个对象,这个对象被称为_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对象)有不同的行为

bnlyeluc

bnlyeluc3#

一个NestedDict可以解决这个问题

from ndicts import NestedDict

def tree_traverse(tree, k):
    nd = NestedDict(tree)
    for key, value in nd.items():
        if k in key:
            return value
>>> tree = {"a": 12, "g":{ "b": 2, "c": 4}, "d":5}
>>> tree_traverse(tree, "d")
5

要安装ndictspip install ndicts

相关问题