# Picking the smallest value in a list using recursion

This is the code I wrote in order to find the smallest value in a list using recursion.However I feel like there would be a better way to do this?

def minimum(lst):
"""
parameters : lst of type list
return : the value of the smallest element in the lst
"""
if len(lst) == 1:
return lst[0]

if lst[0] < lst[1]:
lst.append(lst[0])
return(minimum(lst[1:]))
else:
return(minimum(lst[1:]))

• The best way would of course be to use the built-in min ;) I added the recursion and reinventing-the-wheel tags. – Graipher Nov 11 '18 at 15:41

Instead of adding back to the list to maintain an accumulator (the current minimum in this case), I'd just add a second parameter to the function, and allow it to default to None:

# acc, the accumulator, represents the current lowest found
def my_minimum(lst, acc = None):
if not lst: # If the list is empty, return the current lowest
return acc

# Head is the first element, and the tail is the rest of the list
# This is a common pattern when recursively iterating a list

# The first time this is run, "not acc" fails, and it defaults to head
new_acc = head if not acc or head < acc else acc

return my_minimum(tail, new_acc)

lst = [2, 3, 4, 9, 2, -2]

print(my_minimum(lst))
-2


Note though that head, *tail = lst, is quite inefficient, as it requires making an entire copy to construct tail. I'm using it here for brevity.

• what does the asterisk before tail do ? – Mister Tusk Nov 10 '18 at 20:23
• It unpacks the rest of the list. That line is basically equivalent to head, tail = lst[0], lst[1:]. – Carcigenicate Nov 10 '18 at 20:27

Remove the else branch and push the last return statement to the same scope as the if-statement. Efficiency-wise, keep an eye on the stack size and memory use. Recursion is elegant but sometimes memory can grow exponentially if you are not careful.

It would be more efficient to not modify the list. If the first element is the smallest you now make n new lists. You need a parameter for the index of the minimum element found so far and the current index. If you don't want to modify the existing function you can make an inner function with the necessary params.