Adib Baji
Adib Baji

Reputation: 79

Python - get the path of a given item from a dictionary

I have a function that converts a file path into a dictionary:

def get_directory_structure(rootdir):
    """
    Creates a nested dictionary that represents the folder structure of rootdir
    """
    dir = {}
    rootdir = rootdir.rstrip(os.sep)
    start = rootdir.rfind(os.sep) + 1
    for path, dirs, files in os.walk(rootdir):
        folders = path[start:].split(os.sep)
        subdir = dict.fromkeys(files)
        parent = reduce(dict.get, folders[:-1], dir)
        parent[folders[-1]] = subdir
    return dir

Example output for this:

path_dict = {'Desktop': {
               'sensup.sh': None, 
               'sensdown.sh': None, 
               '1': {
                  '2': {
                     '3': {
                        '4': {}}}}}}

I need to create a function that when given the name of a file or folder from this directory, it outputs its path. For example get_directory('3', path_dict) would output Desktop/1/2/3.

Here's what I tried:

def get_path_from_dict(base_path, base_name, ob, path=''):
        if ob and base_name in list(ob.keys()):
            path = f"{base_path}{path}/{base_name}"
            print(path)
            return path
        elif not ob:
            pass
        else:
            for key, value in sorted(ob.items()):
                get_path_from_dict(base_path, base_name, value, f'{path}/{key}')

Where base_path is the beginning of the full path, so home/user in this case, base_name is the file name to be searched for, and ob is the path dictionary. When I print the final path, it comes out correctly, but when I print the return value it comes out as None and I'm not sure why.

Output of print(get_path_from_dict('/home/user', "3", path_dict)):

/home/user/Desktop/1/2/3 ((from print))
None                     ((from return value))

Upvotes: 0

Views: 1128

Answers (1)

Hadi Hajihosseini
Hadi Hajihosseini

Reputation: 715

The reason that you get None is because you forgot to put the return keyword in your code when your are calling this function recursively.

You are doing this recursively so in the last line of your code you have to add return keyword at the beginning of the line: (this is your code but with a minor change to fix it)

def get_path_from_dict(base_path, base_name, ob, path=''):
    # other codes
    # other codes

    else:
        for key, value in sorted(ob.items()):
            ###################################
            # notice the return keyword below #
            ###################################
            return get_path_from_dict(base_path, base_name, value, f'{path}/{key}')

I executed this code with your input and it works fine. If you have any question ask me my friend.

Upvotes: 1

Related Questions