Yes, it's a good algorithm. All relevant tests have been done (stop condition ok, limit ok indexes), in fact the test by len(ls) == 0
is half redundant: if n >= 0
- condition necessary to pass the first if
- is true, then the condition n < len(ls)
is only true if len(ls) > 0
. There is no unnecessary copy of objects (the same list is always used) and is still present at tail recursion - if the implementation takes advantage of this, your code can be as efficient as an iterative (unfortunately does not seem to be the case with CPython).
What I did not understand is why you return False
if the list is empty and None
otherwise. I even understand that you might want to give a different output if n
is invalid (negative), but an empty list, in my view, should be a valid entry - treated indistinctly from the other entries.
How much to do without using the parameter n
, it is possible, although inefficiently:
def print_list_r(ls=[]):
if len(ls) > 0:
print(ls[0])
print_list_r(ls[1:])
That is, if the list is not empty, print the first element and call the function recursively passing as an argument the sublist with the indexes 1
onwards (ending with an empty sublist).