How to transform a list into nested json

Viewed 402

I have a matrix of elements in python structured like this: matrix["S"]=["H","S","SC"]

In my logic the list attached to the matrix key must become a nested json object in which each element of the list contains the following one, and the key must be the outermost object e.g.

"S":{
  "H":{
    "contains":[{
      "S":{
        "contains":[
          "SC":{
            "contains":[
              None
            ]
          }
        }]
      }
    }]
  }
}

My solution is correct and it's something like this:

    for key in matrix:
        temp = None
        for item in reversed(matrix[key]):
            node = {"embedded": item[1]["embedded"], "macroType": item[1]["macroType"], "contains": [temp], "ignore":item[1]["ignore"]}
            temp = {list(item[0].labels)[0]:node}
        response["instances"].append({key:temp})

response["instance"] contains all the objects.

My problem is when "special" cases happen e.g. "V" cannot be contained inside "SC"

matrix["V"]=["H","S","SC","V","VC"] must output

"V":{
  "H":{
    "contains":[{
      "S":{
        "contains":[{
          "SC":{
            "contains":[
              None
            ]
          },{
          "V":{
            "contains":[{
              "VC":{
                "contains":[
                  None
                ]
              }
            }]
          }
        }]
      }
    }]
  }
}

because in my logic, S contains V at the same level of SC and there's a rule that states that SC cannot contain V. How can I pack "V" and "VC" until I can insert inside something but still packing and nesting the following objects?

EDIT my code just nests all the object from the bottom to the top of the list.

"V":{
  "H":{
    "contains":[{
      "S":{
        "contains":[{
          "SC":{
            "contains":[{
              "V":{
                "contains":[{
                  "VC":{
                    "contains":[
                      None
                    ]
                  }
               }]
              }
           }]
          } 
       }]
      }
   }]
  }
}

I really don't know how to implement what I need

2 Answers

To be able to get the output you want on a json file the list should look like this:

matrix["V"]=["H","S",["SC","V"],"VC"]

Because you want SC and V at the same level, but i dont know how to implement it in your code, hope it helps.

A recursive solution. It works by taking the first item from the list and calling the function again with the rest of the list.

The special case mentioned in the question is included, but more cases can be easily included at that position. E.g. you could search the remaining list for a certain element, split the list at its index, rearrange the list, and so on. That should cover most possible special cases.

test = ["H","S","SC","V","VC"]

def nest_list(l, first=True):
    result = {"contains": []}

    # empty list
    if not l:
        result["contains"].append(None)
    
    # last element in list
    elif len(l) == 1:
        result["contains"].append({l[0]: nest_list([], False)})

    # at least 2 elements left in list
    elif len(l) > 1:
        # special cases: Modify this one or add more.
        if l[0] == "SC" and l[1] == "V":
            result["contains"].append({
                l[0]: nest_list([], False),
                l[1]: nest_list(l[2:], False)}
            )

        # normal case 
        else:
            result["contains"].append({l[0]: nest_list(l[1:], False)})

    # first element is not in a "contains"-dict in your example data,
    # so we return it directly. Don't know if really intended.
    if first:
        return result["contains"][0]
    
    # normal return
    else:
        return result

# call
nest_list(test)

Output, created with : print(json.dumps(nest_list(test), indent=2))

{
  "H": {
    "contains": [
      {
        "S": {
          "contains": [
            {
              "SC": {
                "contains": [
                  null
                ]
              },
              "V": {
                "contains": [
                  {
                    "VC": {
                      "contains": [
                        null
                      ]
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    ]
  }
}
Related