1

我有一个嵌套的 json 文件和一个用于查找的字典(参数),我想用查找替换存在格式“<>”的记录字典值。

查字典: params_lookup = {"population":47, "year":2022, "valid":True, "end":"colls", "num":23, "items":"more"}

记录:

record = {"country":"zzzx", "metrics":{"population":"<population> million", "currency":"Euro", "year":"<year>"}, "valid":"<valid>",
          "others":["<num>", 2, 3], "name":"<items>"}

这是我的尝试,但是当查找值为整数或布尔值时失败。

我理解,因为替换需要在查找中使用字符串,所以它会因 TypeError 失败:replace() 参数 2 必须是 str,而不是 int。您能否就如何解决这个问题提出建议。

import re

START_DELIMITER = '<'

END_DELIMITER = '>'

def format_params(d, params_lookup):

    if isinstance(d, list):
        return [format_params(item, params_lookup) for item in d]

    if isinstance(d, dict):
        return {key: format_params(value, params_lookup)
                for key, value in d.items()}

    if isinstance(d, str) and bool(re.search(START_DELIMITER + "\w*" + END_DELIMITER, d)):
        params = re.findall(START_DELIMITER + "(\w*)" + END_DELIMITER, d)

        for param in params:
            if not params_lookup.get(param):
                raise Exception(
                    f" Parameter {START_DELIMITER + param + END_DELIMITER} is not found in the mapping")   
            else:
                d = d.replace(START_DELIMITER + param + END_DELIMITER, params_lookup.get(param))

        return d

    else:
        return d

format_params(record, params_lookup)


期望的结果:

record = {"country":"zzzx", "metrics":{"population":"47 million", "currency":"Euro", "year": 2022}, "valid":True,
          "others":[23, 2, 3], "name":"more"}
4

1 回答 1

1

那是因为 params dict 中的一些值是整数。您可以将其转换为字符串。

d = d.replace(START_DELIMITER + param + END_DELIMITER, str(params.get(param)))

代码还有一些问题。线

        params = re.findall(START_DELIMITER + "(\w*)" + END_DELIMITER, d)

不需要。

整个代码可以简单地是,

def format_params(d, params):
  if isinstance(d, dict):
     return {k: format_params(v, params) for k,v in d.items()}
  if isinstance(d, list):
     return [format_params(item, params) for item in d]
  elif isinstance(d, str):
     for pk, pv in params.items():
       if d == f"<{pk}>":
         d = pv
         break
       else:
         d = d.replace(f"<{pk}>", str(pv))
     return d
  return d
于 2022-01-30T13:58:19.323 回答