递归搜索字典返回完整的hirerachy

时间:2017-01-04 04:28:33

标签: python dictionary search recursion

我的问题陈述是我有搜索查询,我必须返回与保持层次结构的查询匹配的字典。

我能够实现第一个。但我想回归 从开始就完整的层次结构,如下所示

获得此输出:

{"Name":"google search","items":[],"properties":{"id":1,"process":123}

预期产出:

{
    "items":[
    {'Name':'chrome','items':
     [
       {"Name":"google search","items":[],"properties":{"id":1,"process":123}}
     ]
    },
    ]

}

这是我的示例输入:

myinput = {
    "items":[
    {'Name':'firefox','items':[],"properties":{"one":1,"two":2}},
    {'Name':'chrome','items':[
                        {'Name':"stackoverflow","items":[],"properties":{"one":1,"two":2}},
                        {"Name":"google search","items":[],"properties":{"id":1,"process":123}}
                        ],
                        "properties":{"one":1,"two":2}},
    {'Name':'new','items':[],"properties":{"one":1,"two":2}},
    {'Name':'new','items':[],"properties":{"one":1,"two":2}},
    ]
}

这是我迄今为止所尝试的内容

matched_items = []
def resursive_fun(Nodes, searchQuery):
    for key, value in Nodes.iteritems():
        if isinstance(value, list):
            for item in value:
                matchValue = match_items(searchQuery, item['properties'])
                if matchValue:
                    matched_items.append(item)
                resursive_fun(item, searchQuery)
    return matched_items

searchDict = {"id": 1, "process": 123}
resursive_fun(myinput, searchDict)

1 个答案:

答案 0 :(得分:2)

我认为您需要从任何成功的递归调用的返回值构建返回值,而不是使用全局列表(如果您需要进行多次搜索,这将导致各种问题)。如果没有匹配,你应该返回具有特殊含义的东西(如None)。

尝试这样的事情:

def recursive_search(data, query):
    if match_items(searchQuery, data["properties"]):            # base case
        return data

    if "items" in data and isinstance(data["items"], list):     # recursive case
        for item in data["items"]:
            x = recursive_search(item, query)
            if x is not None:                    # recursive search was successful!
                return {"Name": data["Name"], "items": [x]}

    return None                          # if search is not successful, return None

return None可以省略,因为None是不返回任何其他内容的函数的默认返回值。但我认为,当None具有某种意义时,最好明确表达,就像在这里一样。

如果您不想只找到第一个匹配的结果,而是所有匹配的结果,那么您需要将一些更微妙的行为替换为早期的return调用,如果匹配则只返回一个值找到了某个地方:

def recursive_search(data, query):
    result = {}

    if if "properties" in data and match_items(searchQuery, data["properties"]):
        result["properties"] = data["properties"]

    if "items" in data and isinstance(data["items"], list):
        for item in data["items"]:
            result_items = []
            x = recursive_search(item, query)
            if x is not None:
                result_items.append(x)
        if result_items:         # recursive search found at least one match
            result["items"] = result_items

    if result:      # some part of the search found a match (either here or deeper)
        if "Name" in data:
            result["Name"] = data["Name"]
        return result
    else:
        return None

您还可以在失败的匹配项上返回空字典,而不是None。为此,请将结尾附近的if result: if "Name" in data:行更改为单行if result and "Name" in data:,然后无条件地执行return result(取消else: return None块并取消if x is not None块。将递归案例中的if x检查更改为git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master`