2016-08-08 5 views
0

サードパーティのAPIには、APIパラメータで送信する必要がある膨大なデータがあります。入力データはCSV形式でアプリケーションに送られます。ネストされた辞書を、すべてのレベルの別の辞書にコピーします。

私はCSV DictReaderによって平面dict形式で約120列を含むCSVのすべての行を受け取ります。

file_data_obj = csv.DictReader(open(file_path, 'rU')) 

これは私に次の形式で、各行与えます:

CSV_PARAMS = { 
    'param7': "Param name", 
    'param6': ["some name"], 
    'param5': 1234, 
    'param4': 999999999, 
    'param3': "some ", 
    'param2': {"x name":"y_value"}, 
    'param1': None, 
    'paramA': "", 
    'paramZ': 2.687 
} 

を空白値を持つキーとして、すべてのサードパーティのAPIパラメータを含む1つのネストされた辞書があります。

eg. API_PARAMS = { 
    "param1": "", 
    "param2": "", 
    "param3": "", 
    "param4": { 
     "paramA": "", 
     "paramZ": {"test1":1234, "name":{"hello":1}}, 
     ... 
    }, 
    "param5": { 
     "param6": "", 
     "param7": "" 
    }, 
    ... 
    } 

すべてのCSV値をAPIパラメータに動的にマッピングする必要があります。次のコードは動作しますが、最大で3レベルのネストだけです。

def update_nested_params(self, paramdict, inpdict, result={}): 
    """Iterate over nested dictionary up to level 3 """ 
    for k, v in paramdict.items(): 
     if isinstance(v, dict): 
      for k1, v1 in v.items(): 
       if isinstance(v1, dict): 
        for k2, _ in v1.items(): 
         result.update({k:{k1:{k2: inpdict.get(k2, '')}}}) 
       else: 
        result.update({k:{k1: inpdict.get(k1, '')}}) 
     else: 
      result.update({k: inpdict.get(k, '')}) 
    return result 




self.update_nested_params(API_PARAMS, CSV_PARAMS) 

APIパラメータのn個のネスティングでこれを達成する他の効率的な方法はありますか?任意の利用可能な場合、それはsourceから見つけキー、および再帰的でない場合はtemplateの値が別の辞書でを取って、再帰的に(API_PARAMS)を

def update_nested_params(self, template, source): 
    result = {} 
    for key, value in template.items(): 
     if key in source: 
      result[key] = source[key] 
     elif not isinstance(value, dict): 
      # assume the template value is a default 
      result[missing] = value 
     else: 
      # recurse 
      result[missing] = self.update_nested_params(value, source) 
    return result 

このコピー「テンプレート」:

+0

resultのデフォルト値を '{}'に設定すると、複数回呼び出すと意図しない副作用が発生する可能性があります... – donkopotamus

+0

'CSV_PARAMS ['param5']'はどのように 'API_PARAMS ['param5'] '?後者は辞書にマッピングされます。 –

+0

あなたはここでデフォルトのキーワード引数として 'result = {}'を使いたくありません。(Pythonの "Least Astonishment"を参照してください)(http://stackoverflow.com/q/1132941 ) –

答えて

1

あなたは再帰を使用することができます。これにより、レベルがsys.getrecursionlimit()(デフォルトは1000)までネストされます。