2017-08-11 25 views
2

我有一個包含其他字典和列表像這樣一類JSON詞典:Python的可變對象,並且當複製它們

 "A": { 
      "attrib2": "bar", 
      "attrib1": "foo", 
      "B": "b", 
      "C": [ 
       "c1", 
       "c2" 
      ], 
      "D": [ 
       { 
        "attrib3": "baz" 
       }, 
       { 
        "attrib4": "muh" 
       } 
      ] 
     } 

每個值可以是一個列表(dictonaries或值),字典或一個不可變的值(如「c1」或5)。

現在我想搜索特定的值,我通過所需的鍵來引用它們([「A」,「B」]將指向值「b」)。由於在鍵的給定路徑中可能有列表,我將返回所有找到的值。我的功能如下所示:

def getValues(inputDict, keyList): 
    """ 
     works on dicts in json-like format as outputted by complexXmlElement2dict 
    """ 
    values = list() 
    if keyList: 
     key = keyList.pop(0) 
     try: 
      currentValue = inputDict[key] 
     except KeyError: 
      logger.debug("could not find key {}".format(key)) 
      return list() 

     if isinstance(currentValue, dict): 
      additionalValues = getValues(copy.deepcopy(currentValue), list(keyList)) # copy list and dict!! 
      values.extend(additionalValues) 

     elif isinstance(currentValue, list): 
      for subDict in currentValue: 
       assert isinstance(subDict, dict) 
       values.extend(getValues(copy.deepcopy(subDict), list(keyList))) # copy list and dict!! 
     else: 
      values.append(currentValue) 

    return list(values) 

正如你所看到的,我對這裏使用的可變對象有些偏執。我正在複製留下的鍵列表以查找正確的值以及我每次使用的字典。我的函數按預期工作,但我認爲由於不必要地複製所有這些對象而造成大量開銷。

什麼時候可以省略複製這個例子中的字典和列表,爲什麼?試錯法是沒有選擇的,因爲我沒有所有可能的輸入字典,也因爲我想獲得更好的理解。我應該補充一點,我已經閱讀了很多python中的可變對象的例子和解釋,儘管我認爲我理解了我覺得不夠舒服的概念,但是我認爲這是不必要的,因爲其他人依賴於此代碼的正確性。

getValues(copy.deepcopy(currentValue), list(keyList)) 
getValues(copy.deepcopy(subDict), list(keyList))) 
return list(values) 

我正在使用Python 2.7。

回答

0

我找不到任何理由複製字典或列表。你沒有更新他們中的任何一個。你只是從中提取數據。所以只需在遞歸函數中傳遞參考。

+0

我的keyList每次更深一層時都會更新:key = keyList.pop(0),每當我找到一個匹配搜索模式的值時,我的值列表就會更新。字典currentValue也指向每次大字典的不同部分。 – Stefan

+0

關於按鍵列表,您可以每次通過同一列表並傳遞索引以確定要處理的密鑰。關於字典currentValue,它指向不同的大字典並不重要,如果你沒有更新它,你可以使用淺拷貝。無需深層複製。關於價值清單,您總是創建一個新清單,並將其追加到前一個清單中。你需要理解遞歸函數的概念。 –

相關問題