1

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'}}]}
Kalpesh
  • 694
  • 2
  • 8
  • 28

1 Answers1

1

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
Saxtheowl
  • 4,136
  • 5
  • 23
  • 32
  • 1
    Seems you just added one line between return statement.. which is not helping.. I am already returning this simplified_json. is there anything else you did? – Kalpesh Apr 27 '23 at 23:45
  • I have added a base case for the recursion and checking if the object contains nested dictionaries before performing recursion – Saxtheowl Apr 27 '23 at 23:49
  • Correct, I was also checking the base case, if the object contains list before recursion, but it was not working, if I run your code it's working but my list's object are not getting converted where more than one element is present.. though it doesn't solved my problem, but this issue got resolved thanks. – Kalpesh Apr 27 '23 at 23:58