简体   繁体   English

递归搜索字典,返回完整的收入

[英]Recursively searching through dictionary returning complete hirerachy

My problem statement is I have search query and I have to return the dictionary matching the query maintaining the hierarchy. 我的问题陈述是我有搜索查询,我必须返回与查询匹配的字典,以维护层次结构。

I am able to achieve the first. 我能够做到第一。 But I want to return the complete hierarchy right from starting, like below 但是我想从一开始就返回完整的层次结构,如下所示

Getting this output: 获取此输出:

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

Expected output: 预期产量:

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

}

This is my sample input: 这是我的示例输入:

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}},
    ]
}

This I what I have tried till now 这是我迄今为止尝试过的

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)

I think you need to build your return value from the return value of any successful recursive call, rather than using a global list (which will cause all sorts of problems if you ever need to do multiple searches). 我认为您需要从任何成功的递归调用的返回值中构建返回值,而不是使用全局列表(如果您需要进行多次搜索,这将导致各种问题)。 You should return something with special meaning (like None ) if there's no match. 如果没有匹配项,则应返回具有特殊含义的内容(如None )。

Try something like this: 尝试这样的事情:

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

The return None could be omitted, since None is the default return value for a function that doesn't return anything else. return None可以省略,因为None是不返回其他任何值的函数的默认返回值。 But I think it's better to be explicit when the None has some meaning, as it does here. 但是,我认为最好在“ None具有某些含义时要明确一些,就像在这里一样。

If you don't just want to find the first matching result, but all matching results, you'll want to replace the early return calls with some more subtle behavior that only returns a value if a match was found somewhere: 如果您不仅要查找第一个匹配结果,而且要查找所有匹配结果,则需要用一些更细微的行为来替换早期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

You could also return an empty dictionary on a failed match, rather than None . 您也可以在失败的匹配中返回一个空字典,而不是None To do that, change the if result: if "Name" in data: lines near the end to the single line if result and "Name" in data: and do the return result unconditionally (unindent it and get rid of the else: return None block). 为此,将if result: if "Name" in data:行更改为单行if result and "Name" in data: if result: if "Name" in data:行的末尾,并无条件地执行return result (取消缩进并删除else: return None )。 Change the if x is not None check in the recursive case to if x . 将递归情况下的if x is not None更改为if x

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM