boyboy_290
boyboy_290

Reputation: 37

counting the number of elements of a list using recursive function without using len

I saw this code:

def list_length(my_lis):
    if mylist:
        return 1 + list_length(my_lis[1:])
    return 0

This code counts the number of elements in the list recursively without using len function. Can someone please explain the list_length(my_lis[1:]) and how it gets added to 1 because from my understanding, my_lis[1:] gives the list without the first element. So how can this give the number of elements in a list?

Upvotes: 1

Views: 841

Answers (3)

Matt
Matt

Reputation: 1145

Ahh recursion, tends to make things more complex than they need to be, but it's still cool!

Let's add some debug code to see what is happening

def list_length(my_lis):
    if my_lis:
        print(my_lis)
        length = list_length(my_lis[1:])
        print(str(my_lis) + " returning 1 + " + str(length))
        return 1 + length 
    print("Empty List! Return 0")
    return 0

test_list = ['1', '2', '3', '4']

answer = list_length(test_list)

print("Answer: " + str(answer))

This will output:

['1', '2', '3', '4']
['2', '3', '4']
['3', '4']
['4']
Empty List! Return 0
['4'] returning 1 + 0
['3', '4'] returning 1 + 1
['2', '3', '4'] returning 1 + 2
['1', '2', '3', '4'] returning 1 + 3
Answer: 4

Notice how we only reach the base case (return 0) after the list is empty. Also notice that the number doesn't start going up until AFTER we hit the base case. Only after we reach an empty list can we start going back up the chain and counting 1 + whatever the last function got.

Upvotes: 3

Ashish M J
Ashish M J

Reputation: 700

Consider

my_lis = [1,2,3]

if condition satisfies because list isn't empty so returns 1+list_length(my_lis[1:]) meaning my_lis[1:] means [2,3] . So to generalize it you are decreasing length of list by one, that is you count the first element and ignore the first element.

return 1+ list_length(my_lis[1:])            #my_lis=[2,3]
return 1+ 1+ list_length(my_lis[1:])         #my_lis=[3]
return 1+ 1+ 1+ list_length(my_lis[1:])      #my_lis=[]
return 1+ 1+ 1+ 0

Upvotes: 1

ApplePie
ApplePie

Reputation: 8942

This goes as follows:

  • If my_lis is not falsy (assumes non-empty list)
  • Return 1 + call the same func on a list of the next item until the last
  • If this new list is not falsy
  • Return 1 + call the same func on a list of the next item until the last
  • ...

This goes on until my_lis[1:] returns None, in this case instead of returning 1 we will return 0 and we do not trigger another recursive call.

Going from the innermost instead:

  • my_lis is empty, return 0
  • my_lis is not empty, return 1 + 0
  • my_lis is not empty, return 1 + (1 + 0)
  • my_lis is not empty, return 1 + (1 + 1 + 0)
  • ...

This is how you end up with a list length.

Upvotes: 1

Related Questions