将嵌套字典复制到具有所有级别的另一个字典。

时间:2016-08-08 07:18:30

标签: python csv dictionary

对于某些第三方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参数作为具有空值的键。

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次嵌套,还有其他有效的方法来实现这一点吗?

1 个答案:

答案 0 :(得分:1)

你可以使用递归:

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

这会复制'模板' (API_PARAMS)递归地,从source获取任何密钥(如果可用),如果没有,则递归,但template中的值是另一个字典。这可以处理最多sys.getrecursionlimit()级别的嵌套(默认值为1000)。