pythonrecursionnested-json

Recursion error while simplifying nested json to flat in python


I am trying flatten the json object so that I can create plain csv file out of it. But it is throwing

RecursionError: maximum recursion depth exceeded while calling a Python object

Code which I have written in python, calling simplify_multy_nested_json_recur() :

def simplify_multy_nested_json_recur(obj):
    kv = convert_list_to_kv(obj)
    simplified_json = simplify_nested_json(kv)
    if any(isinstance(value, list) for value in simplified_json.values()):
        simplified_json = simplify_multy_nested_json_recur(simplified_json)
    return simplified_json

def simplify_nested_json(obj, parent_key=""):
    """
    Recursively simplifies a nested JSON object by appending key names with the previous node's key.
    """
    new_obj = {}
    for key in obj:
        new_key = f"{parent_key}_{key}" if parent_key else key
        if isinstance(obj[key], dict):
            new_obj.update(simplify_nested_json(obj[key], parent_key=new_key))
        else:
            new_obj[new_key] = obj[key]
    return new_obj

def convert_list_to_kv(obj):
    """
    Converts list elements into key-value pairs if the list size is 1 in a JSON object.
    """
    for key in obj:
        if isinstance(obj[key], list) and len(obj[key]) == 1:
            obj[key] = obj[key][0]
        elif isinstance(obj[key], dict):
            convert_list_to_kv(obj[key])
    return obj

Input:

{'resourceType':'CP','id':'af160c6b','period':{'start':'1987-12-21T06:22:41-05:00'},'careTeam':[{'reference':'79a33a776b59'}],'goal':[{'reference':'c14'},{'reference':'b88'}],'activity':[{'detail':{'code':{'coding':[{'code':'160670007','display':'Diabetic diet'}],'text':'Diabetic diet'},'status':'in-progress'}}]}

Solution

  • You have an infinite loop due to continuous recursion, because your condition to stop recursion never happen.

    Here is how I would modify your code:

    def simplify_multy_nested_json_recur(obj):
        kv = convert_list_to_kv(obj)
        simplified_json = simplify_nested_json(kv)
    
        if any(isinstance(value, dict) for value in simplified_json.values()):
            simplified_json = simplify_multy_nested_json_recur(simplified_json)
        
        return simplified_json
    
    def simplify_nested_json(obj, parent_key=""):
        new_obj = {}
        for key in obj:
            new_key = f"{parent_key}_{key}" if parent_key else key
            if isinstance(obj[key], dict):
                new_obj.update(simplify_nested_json(obj[key], parent_key=new_key))
            else:
                new_obj[new_key] = obj[key]
        return new_obj
    
    def convert_list_to_kv(obj):
        for key in obj:
            if isinstance(obj[key], list) and len(obj[key]) == 1:
                obj[key] = obj[key][0]
            elif isinstance(obj[key], dict):
                convert_list_to_kv(obj[key])
        return obj