2017-01-04 28 views
0

我的問題是我有搜索查詢,我必須返回匹配查詢維護層次結構的字典。遞歸搜索字典返回完整hirerachy

我能夠實現第一個。但我想直接從開始返回 完整的層次,如下面

獲得這樣的輸出:

{"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) 

回答

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

+0

這工作正常。但是,如果我的搜索查詢匹配輸入集中的多個元素,則此算法不會返回所有匹配結果。例如,如果搜索字典是「searchDict = {」process「:123}',則這個屬性中的兩個項目具有相同的值。在這種情況下,它應該返回兩個帶有層次結構的字典。 – vr22

+0

如果您需要處理多個匹配,您可以將邏輯稍微更改爲不會發生短路。在這種情況下唯一棘手的事情是決定如何處理匹配項目的子項目。他們應該總是被包括在內嗎? – Blckknght

+0

子項目不一定全部包括在內。你能否更詳細地解釋如何不進行短路處理幾場比賽的情況?會對我很有幫助。提前致謝。 – vr22