Search code examples
pythonrecursiondata-structurestreerecursive-datastructures

Deep python dictionary recursion


I have a python dictionary:

d = {
    "config": {
        "application": {
            "payment": {
                "dev": {
                    "modes": {"credit,debit,emi": {}},
                    "company": {
                        "address": {
                            "city": {"London": {}},
                            "pincode": {"LD568162": {}},
                        },
                        "country": {"United Kingdom": {}},
                        "phone": {"7865432765": {}},
                    },
                    "levels": {"0,1,2": {}},
                },
                "prod": {"modes": {"credit,debit": {}}, "levels": {"0,1": {}}},
            }
        }
    }
}

I want to change it to something like this(if the value is empty{} then make the key as value for its parent)

d = {
    "config": {
        "application": {
            "payment": {
                "dev": {
                    "modes": "credit,debit,emi",
                    "company": {
                        "address": {
                            "city": "London", 
                            "pincode": "LD568162"
                        },
                        "country": "United Kingdom",
                        "phone": "7865432765"
                    },
                    "levels": "0,1,2"
                }, 
                "prod": {
                    "modes": "credit,debit",
                    "levels": "0,1"
                }
            }
        }
    }
 }

i tried to write the code to traverse this deep dictionary, but couldn't modify it to get the above output. Please help.

def recur(json_object):
    for x in list(json_object.items()):
        print(x)
        recur(json_object[x])

d={'config': {'application': {'payment': {'dev': {'modes': {'credit,debit,emi': {}}, 'company': {'address': {'city': {'London': {}}, 'pincode': {'LD568162': {}}}, 'country': {'United Kingdom': {}}, 'phone': {'7865432765': {}}}, 'levels': {'0,1,2': {}}}, 'prod': {'modes': {'credit,debit': {}}, 'levels': {'0,1': {}}}}}}}

Solution

  • Solution 1

    We can use a non-recursive approach with queues to enqueue each inner/nested element of the document and put as value if the nested value is just {}:

    # d = ...
    
    queue = [d]
    
    while queue:
        data = queue.pop()
        for key, value in data.items():
            if isinstance(value, dict) and list(value.values()) == [{}]:
                data[key] = list(value.keys())[0]
            elif isinstance(value, dict):
                queue.append(value)
    
    print(d)
    

    Output

    {
        "config": {
            "application": {
                "payment": {
                    "dev": {
                        "modes": "credit,debit,emi",
                        "company": {
                            "address": {
                                "city": "London",
                                "pincode": "LD568162"
                            },
                            "country": "United Kingdom",
                            "phone": "7865432765"
                        },
                        "levels": "0,1,2"
                    },
                    "prod": {
                        "modes": "credit,debit",
                        "levels": "0,1"
                    }
                }
            }
        }
    }
    

    Solution 2

    Here's a recursive approach

    # d = ...
    
    def recur(data):
        for key, value in data.items():
            if isinstance(value, dict) and list(value.values()) == [{}]:
                data[key] = list(value.keys())[0]
            elif isinstance(value, dict):
                recur(value)
    
    recur(d)
    
    print(d)
    

    Output

    • Same as Solution 1