2017-08-11 12 views
2

をコピーするとき:Pythonの可変オブジェクトと私はそうのような他の辞書やリストを含むJSONのような辞書持っている彼らに

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

は、それぞれの値が(dictonariesまたは値の)リストすることができ、辞書や不変の値( "c1"や5など)。

私はそれらに到達するために必要なキー(["A"、 "B"]は値 "b"を指す)によって参照する特定の値を検索したいと思います。与えられたキーのパスにリストが存在する可能性があるので、私はすべての見つかった値を返しています。 My機能は、次のようになります。あなたが見ることができるように

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については、別の大きな辞書を指していても問題ありません。更新していない場合は、浅いコピーを使用できます。ディープコピーする必要はありません。値リストについては、常に新しいリストを作成して、前のリストに追加します。再帰関数の概念を理解する必要があります。 –

関連する問題