While I think Martijn Pieters answer addresses the primary issue in his answer (you need to return from the recursive case), I don't think his suggested code will work right.
You're trying to implement a depth-first search for the rqfile
value in the nested dictionary
dict. But your current code doesn't handle the recursive case correctly. It needs to respond appropriately if the result is found in one of its recursive calls, or if the recursive call failed to find the target.
Here's what I think you need, with some things renamed or rearranged for clarity:
def get_path(directory, rqfile, prefix=[]):
for filename, value in directory.items():
path_list = prefix + [filename]
if not isinstance(value, dict): # base case
path = os.path.join(*path_list)
if rqfile in path: # Found the file. Do you want to do something
return path # with the value here, or is it junk?
else: # recursive case
try:
return get_path(value, rqfile, path_list) # this only returns if
except ValueError: # the recursion doesn't raise
pass
raise ValueError("Requested file not found") # not found here or in children
Example usage:
>>> directory = {"a": "a info",
"b": {"c": "b/c info", "d": "b/d info"},
"e": {"f": "e/f info", "g": {"h": "e/g/h info"}}}
>>> print(get_path(directory, "h"))
e\g\h
>>> print(get_path(directory, r'g\h'))
e\g\h
If you don't want to raise exceptions when the file is not found, you could also return a sentinel value like None
in place of the last line, and check for the sentinel value it in the recursive case instead of the try
/except
:
result = get_path(value, rqfile, path)
if result is not None:
return result