Handle recursion

Published on: 2021-06-25

Recursion of paths to file originally created as dict

The goal of this example is to join path parts save in dict to full path and saved to list.

Let imagine that we parse paths to file to dict as following:

paths_as_dict = {
                {'home':
                    {'web_app1': {
                        'index1.html': b'Content of file',
                        'index2.html': b'Content of file'}
                    },
                    {'web_app2': {
                        'index.html': b'Content of file'},
                        'static': {'image.jpg': b'Content of file'}
                    }
                }
                'index.html',
            }

result of example shoudld be:

result = [
            'home/web_app1/index1.html',
            'home/web_app1/index2.html',
            'home/web_app2/index.html',
            'home/web_app2/static/image.jpg',
            'index.html'
        ]

## Solution without recursion

result = []
for key1, value1 in paths_as_dict.items():
    if isinstance(value1, bytes):
        result.append(key1)
    else:
        for key2, value2 in value1.items():
            if isinstance(value2, bytes):
                result.append(key1 + '/' + key2)
            else:
                for key3, value3 in value2.items():
                    if isinstance(value3, bytes):
                        result.append(key1 + '/' + key2 + '/' + key3)
                    else:
                        ...

This solution is fine. It is working and we get the result. But it is obvious the solution will work fine only for specific input.

This solution have these problems:

To resolve problems above we use recursion.

Recursion solution

Arguments will be variable which are updated in solution without recusrion: - path, which is saved to result path_so_far, - and input dictionary input_dict.

result = []

def recursion_solution(input_dict, path_so_far):
    for key, value in input_dict.items():
        if isinstance(value, bytes):
            result.append(path_so_far + key)
        else:
            recursion_solution(value, path_so_far + key + '/')

recursion_solution(paths_as_dict, '')

Obviously, the recursion solution is much more elegant then previous solution.

The most hardest part was to define variable path_so_far in combination with variable key and slash ‘/’.