I need to define a recursive function that takes two parameters (a list with names and an initial), and returns a new list with all the names that start with the initial.
Right now I have got this code, and i don't know why it doesn't work:
def filter_names(names, initial):
result = []
if names[0][0] == initial:
result.append(names[0])
else:
filter_names(names[1:], initial)
return result
CodePudding user response:
Your recursive call isn't appending to the same result
that's defined in the outer scope.
Usually in a recursive function you combine the result of your recursive call with whatever work you've done in the current frame. In this case that might look like this:
def filter_names(names, initial):
if not names:
return []
return (
[names[0]] if names[0][0] == initial else []
) filter_names([1:], initial)
CodePudding user response:
I'm going to say that this is not a good use of recursion, but you have some misconception about how to go about it:
def filter_name(names, initial) -> list[str]:
if 0 == len(names): # base case
return []
else: # iterative case
head = names[0] # The first element
tail = names[1:] # Everything else
tail_names = filter_name(tail, initial) # Get the result of the recursive call on 'everything else'
if head[0] == initial: # Decide if the first element should change your result
tail_names.append(head) # If so, modify your result
return tail_names # Return it
For recursion you need to define a base case and an iterative step. The iterative step should call the function again, with a smaller input. Then it should add (any necessary) change into the returned result before returning it.
This code is unnecessarily explicit - there are more concise ways to do it, but it illustrates what is going on.
The base case is that you have an empty list of names. You know what should be returned in this case - an empty list.
The iterative case should first figure out what the next-smallest version of the problem is. Here, it is a list that is one shorter, tail
. First get the result of recursing with that new, shorter input. With that result, you then take the difference - in this case head
and decide if you need to modify the result. After that, you return that result.
That said, there is a far easier, efficient and idiomatic way to do this in python:
result = [name for name in names if name[0] == initial]