Your first attempt is almost perfect, the only mistake is that you return the result of searching through the first list/tuple at the current depth, regardless of whether the item
was found or not. Instead, you need to check for a positive result, and only return if it is one. That way you keep iterating through the current depth until you either find the item
or it is not found at all.
So you need to change:
return traverse(S[i], item, indices + [i], atDepth + 1)
to something like:
t = traverse(S[i], item, indices + [i], atDepth + 1) if t != ([], -1): return t
Full code:
def traverse(S, item, indices=[], atDepth=0): # If the sequence is empty, return the 'item not found' result if not S: return ([], -1) else: # For each element in the sequence (breadth-first) for i in range(len(S)): # Success condition base case: found the item! if S[i] == item: return (indices + [i], atDepth) # Recursive step (depth-first): enter nested sequence # and repeat procedure from beginning elif type(S[i]) in (list, tuple): t = traverse(S[i], item, indices + [i], atDepth + 1) if t != ([], -1): return t # Fail condition base case: searched the entire length # and depth of the sequence and didn't find the item, so # return the 'item not found' result else: print("We looked everywhere but didn't find " + str(item) +" in " + str(S) +".") return ([], -1)
Output for your two test cases:
>>> traverse(L, 7)([3, 1, 2, 4], 3)>>> traverse(L, 9)We looked everywhere but didn't find 9 in [6, 6.25, 6.5, 6.75, 7].We looked everywhere but didn't find 9 in (4, 5, [6, 6.25, 6.5, 6.75, 7]).We looked everywhere but didn't find 9 in [3, (4, 5, [6, 6.25, 6.5, 6.75, 7])].We looked everywhere but didn't find 9 in [8, ()].We looked everywhere but didn't find 9 in [[8, ()]].([5, 0, 0, 0], 3)
Note as pointed out by @FreddyMcloughlan, atDepth
is simply the length of the returned list minus 1. So you can remove that parameter from the function call and just use:
def traverse(S, item, indices=[]): # If the sequence is empty, return the 'item not found' result if not S: return ([], -1) else: # For each element in the sequence (breadth-first) for i in range(len(S)): # Success condition base case: found the item! if S[i] == item: return (indices + [i], len(indices)) # Recursive step (depth-first): enter nested sequence # and repeat procedure from beginning elif type(S[i]) in (list, tuple): t = traverse(S[i], item, indices + [i]) if t != ([], -1): return t # Fail condition base case: searched the entire length # and depth of the sequence and didn't find the item, so # return the 'item not found' result else: print("We looked everywhere but didn't find " + str(item) +" in " + str(S) +".") return ([], -1)