The problem is that you unconditionally return the route in the very first iteration of the loop, i.e. after following the first branch, regardless of whether that actually led to end. Instead, you have to check whether the route returned is not None (None being implicitly returned after the loop). You also should check whether consider in d before starting the loop. Also, you should not overwrite the original value of route inside the loop. In fact, the route parameter is useless, as it will ever only be "".
def path(d, consider, end):
if consider == end:
return ''
elif consider in d:
for e in d[consider]:
res = path(d, e, end)
if res is not None:
return e + res
If you want all the routes that lead to end, use yield instead of return. In this case, the condition is not needed, as this will only yield valid paths in the first place, and never None, but you need another loop to iterate the different successful paths, if any.
def path(d, consider, end):
if consider == end:
yield ''
elif consider in d:
for e in d[consider]:
for res in path(d, e, end):
yield e + res
This way, list(path(d,'a','d')) results in ['bcd', 'd']
Note, however, that on a cyclic graph this may lead to an infinite recursion, even if there is a short path to the goal, depending on the layout of the graph. You could counter this by either passing an ever-growing set of already visited nodes in each iteration, or popping visited nodes from the graph d itself, or by including a counter of already visited nodes, and stopping if that counter is higher than the number of nodes in the graph.
returnindeed inside theforloop?returnin yourforloop. That means your loop will only run one iteration, and then the function is exited.