0

I am working with a system that unfortunately; uses nested json objects with the same key name. Based on some input data based on 0 to n elements I need to create this object dynamically but not sure how to do this with python correctly.

Here is what my json looks like in this example there are 3 expressions..

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

                }
            }
        }
    }
}

I've been trying to dynamically create this but even when I try to add it manually..

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))

I get an error saying "ValueError: Circular reference detected".

Now even if this did work imagine having to do this for 250 objects! In some type of for loop..

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

There's no "get_json_root" or "append" method on a dict object that I am aware of. How the heck would I do this?

2 Answers 2

1

Instead of assigning template_object to ["metricExpressionTemplate"]["expression1"] and ["metricExpressionTemplate"]["expression1"]["expression1"], use a factory method to generate new template objects each time. So:

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))

As for adding the template_object when you have an object of unknown depth, you could use a recursive method, with each call checking whether the object passed to it has a key "expression1":

def addExpression(obj):
    if "expression1" in obj.keys():
        addExpression(obj["expression1"])
    else:
        obj["expression1"] = newTemplateObject()
Sign up to request clarification or add additional context in comments.

Comments

0

The error is occurring because you are attempting to reuse the same object inside itself. This can be overcome by generating a new dictionary each time it is needed. Then this can be performed in a loop through a recursive system, for example:

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.