使用相同的键名动态创建嵌套的json对象?

时间:2018-03-26 03:10:01

标签: python json

我正在使用一个不幸的系统;使用具有相同键名的嵌套json对象。基于一些基于0到n个元素的输入数据,我需要动态创建这个对象,但不确定如何正确地使用python。

这是我的json在这个例子中看起来像有3个表达式..

{
    "metricExpressionTemplate": {
        "metricExpressionType": "Boolean",
        "operator": {
            "type": "PLUS"
        },
        "expression1": {
            "metricExpressionType": "Boolean",
            "operator": {
                "type": "PLUS"
            },
            "expression1": {
                "metricExpressionType": "Boolean",
                "operator": {
                    "type": "PLUS"
                },
                "expression1": {
                    "metricExpressionType": "Boolean",
                    "operator": {
                        "type": "PLUS"
                    }

                }
            }
        }
    }
}

我一直试图动态创建它,但即使我尝试手动添加它..

import json

expression_object = {}
template_object = {
    "metricExpressionType": "Boolean",
    "operator": {
            "type": "PLUS"
        },
    }

expression_object["metricExpressionTemplate"]["expression1"] = template_object
expression_object["metricExpressionTemplate"]["expression1"]["expression1"] = template_object

print(json.dumps(expression_object))

我收到错误消息“ValueError:检测到循环引用”。

现在,即使这确实有效,也可以想象必须为250个物体做这个!在某些类型的for循环..

for i in range(0,200):
    # Add Expression objects dynamically..
    expression_object["metricExpressionType"]["expression1"] = template_object

我所知道的dict对象上没有“get_json_root”或“append”方法。我该怎么办呢?

2 个答案:

答案 0 :(得分:1)

不是将template_object分配给["metricExpressionTemplate"]["expression1"]["metricExpressionTemplate"]["expression1"]["expression1"],而是每次都使用工厂方法生成新的模板对象。所以:

import json

def newTemplateObject():
    t = {
        "metricExpressionType": "Boolean",
        "operator": {
                "type": "PLUS"
            },
        }
    return t


expression_object = {}
expression_object["metricExpressionTemplate"] = newTemplateObject()
expression_object["metricExpressionTemplate"]["expression1"] = newTemplateObject()
expression_object["metricExpressionTemplate"]["expression1"]["expression1"] = newTemplateObject()
print(json.dumps(expression_object))

对于有深度未知的对象时添加template_object,可以使用递归方法,每次调用都会检查传递给它的对象是否有一个键" expression1":

def addExpression(obj):
    if "expression1" in obj.keys():
        addExpression(obj["expression1"])
    else:
        obj["expression1"] = newTemplateObject()

答案 1 :(得分:0)

发生错误是因为您试图在自身内部重用相同的对象。这可以通过每次需要时生成新字典来克服。然后,这可以通过递归系统循环执行,例如:

import json

def get_contents():
  return {
    "metricExpressionType": "Boolean",
      "operator": {
          "type": "PLUS"
      }
  }

def add_contents(d, contents, remaining):
  d['expression1'] = contents()
  if remaining > 0:
    add_contents(d['expression1'], contents, remaining - 1)

objects = []
templates = ['metricExpressionTemplate', 'b', 'c']

for template_name in templates:
  d = {template_name: get_contents()}
  add_contents(d, get_contents, 2)
  objects.append(d)

print json.dumps(objects, indent=2)