Yes, it is a good algorithm. All relevant tests have been done (stop condition ok, limit of the indexes ok), incidentally the test by len(ls) == 0
is kind of redundant: if n >= 0
- necessary condition to pass through the first if
- is true, so the condition n < len(ls)
will only be 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 don’t understand is why you return False
if the list is empty and None
otherwise. I even understand that you may want to take a different exit if n
is invalid (negative), but an empty list, in my conception, should be a valid entry - treated indistinctly from other entries.
How to do without using the parameter n
, is possible yes, 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 argument to sublist with the indexes 1
onwards (ending with an empty sublist).