基于键和值的嵌套dict条件递归搜索

2024-06-17 16:34:32 发布

您现在位置:Python中文网/ 问答频道 /正文

在SQL方面,我尝试基于查询中使用的表构建依赖关系图。我设法将它们解析到一个嵌套字典中,其深度根据子查询的嵌套方式而定,并且每个嵌套dict块的深度可能不同

sql = {"select":{"value":"some value"},
       "from":[{"value":"table1","name":"a"},
               {"value":{"select":{"value":"*"},
                         "from":{"value":"table2","name":"b"}}}]}

预期输出为:

["table1","table2"]

我最初的方法是递归搜索from键:

def recurd(d, find = ['from']):
    if isinstance(d, list):
        for i in d:
            yield from recurd(i)
    elif isinstance(d, dict):
        for k,v in d.items():
            if any(i in k for i in find):
                yield v
        for j in d.values():
            yield from recurd(j)

输出:

[{'value': 'table1', 'name': 'a'}, {'value': {'select': {'value': '*'}, 'from': {'value': 'table2', 'name': 'b'}}}]
{'value': 'table2', 'name': 'b'}

虽然这是意料之中的,但我发现基于key和value递归返回所需的值是相当混乱的。我试着四处看看,但似乎大多数应用于嵌套dict的递归示例只看键,类似于上面的示例。你知道吗


Tags: nameinfrom示例forifvaluefind
1条回答
网友
1楼 · 发布于 2024-06-17 16:34:32

函数应该在父键递归时跟踪父键,以便仅当父键为'from'时才能生成值:

def get_tables(d, find=('from',), parent_key=None):
    if isinstance(d, dict):
        if parent_key in find and isinstance(d.get('value'), str):
            yield d['value']
        for k, v in d.items():
            yield from get_tables(v, find, k)
    elif isinstance(d, list):
        for i in d:
            yield from get_tables(i, find, parent_key)

因此list(get_tables(sql))返回:

['table1', 'table2']

相关问题 更多 >