1

I am trying to convert a Json file that looks like

{
#   "item_1":"value_11",
#   "item_2":"value_12",
#   "item_3":"value_13",
#   "item_4":["sub_value_14", "sub_value_15"],
#   "item_5":{
#       "sub_item_1":"sub_item_value_11",
#       "sub_item_2":["sub_item_value_12", "sub_item_value_13"]
#   }
# }

TO something that looks like this:

 {
#   "node_item_1":"value_11",
#   "node_item_2":"value_12",
#   "node_item_3":"value_13",
#   "node_item_4_0":"sub_value_14", 
#   "node_item_4_1":"sub_value_15",
#   "node_item_5_sub_item_1":"sub_item_value_11",
#   "node_item_5_sub_item_2_0":"sub_item_value_12",
#   "node_item_5_sub_item_2_0":"sub_item_value_13"
# }

I am aware that you can't maintain the order of the Json file when converted to CSV. I am considering to do a workaround by loading the JSON data into OrderedDic objects (which cause them to be added in the order that the input document lists them. However, I am new to working with JSON files, as well as OrderedDic function.

To split items into subgroups i used:

def reduce_item(key, value):
        global reduced_item

        #Reduction Condition 1
        if type(value) is list:
            i=0
            for sub_item in value:
                reduce_item(key+'_'+to_string(i), sub_item)
                i=i+1

        #Reduction Condition 2
        elif type(value) is dict:
            sub_keys = value.keys()
            for sub_key in sub_keys:
                reduce_item(key+'_'+to_string(sub_key), value[sub_key])

        #Base Condition
        else:
            reduced_item[to_string(key)] = to_string(value)

But how do I use the orderedDic along with the above code to show this output:

{
    #   "node_item_1":"value_11",
    #   "node_item_2":"value_12",
    #   "node_item_3":"value_13",
    #   "node_item_4_0":"sub_value_14", 
    #   "node_item_4_1":"sub_value_15",
    #   "node_item_5_sub_item_1":"sub_item_value_11",
    #   "node_item_5_sub_item_2_0":"sub_item_value_12",
    #   "node_item_5_sub_item_2_0":"sub_item_value_13"
    # }

I have the below code as well but it does not split each in subgroups based on the conditions of the subtring code above:

import json
from  collections import OrderedDict
with open("/home/file/official.json", 'r') as fp:
    metrics_types = json.load(fp, object_pairs_hook=OrderedDict)
print(metrics_types)

That shows:

enter image description here

Any suggestions?

blhsing
  • 70,627
  • 6
  • 41
  • 76
Coder123
  • 236
  • 1
  • 13

1 Answers1

1

You can use a function that iterates through the given dict or list items and merges the keys from the dict output of the recursive calls:

def flatten(d):
    if not isinstance(d, (dict, list)):
        return d
    out = {}
    for k, v in d.items() if isinstance(d, dict) else enumerate(d):
        f = flatten(v)
        if isinstance(f, dict):
            out.update({'%s_%s' % (k, i): s for i, s in f.items()})
        else:
            out[k] = f
    return out

so that given:

d = {
  "item_1":"value_11",
  "item_2":"value_12",
  "item_3":"value_13",
  "item_4":["sub_value_14", "sub_value_15"],
  "item_5":{
      "sub_item_1":"sub_item_value_11",
      "sub_item_2":["sub_item_value_12", "sub_item_value_13"]
  }
}

flatten(d) returns:

{'item_1': 'value_11',
 'item_2': 'value_12',
 'item_3': 'value_13',
 'item_4_0': 'sub_value_14',
 'item_4_1': 'sub_value_15',
 'item_5_sub_item_1': 'sub_item_value_11',
 'item_5_sub_item_2_0': 'sub_item_value_12',
 'item_5_sub_item_2_1': 'sub_item_value_13'}

The above assumes that you're using Python 3.7 or later, where dict keys are guaranteed to be ordered. If you're using earlier versions, you can use OrderedDict in place of a regular dict.

blhsing
  • 70,627
  • 6
  • 41
  • 76
  • In the same order as shown above. Define the function first, assign a value to your dict `d`, and then call `flatten(d)`. – blhsing Mar 20 '19 at 20:37