[Tutor] Understanding error in recursive function
Martin A. Brown
martin at linux-ip.net
Fri Apr 8 19:34:03 EDT 2016
Greetings Tom,
>As a test I am trying to write a function that returns the sum of
>values
Given the code you pasted, I think you mean 'count' of values,
right? I'll assume that below, because it is a tricky thing to sum
some strings.
>attached to one key in a dictionary. I am wondering why the
>code that I wrote is returning:
>"maximum recursion depth exceeded "
>Here is the code:
Recursion is a great tool, and quite powerful. (Though you may not
need it for this problem.)
>animals = { 'a': ['aardvark'], 'b': ['baboon'], 'c': ['coati']}
>
>x = animals['a']
>
>def howMany(aDict):
> count = 0
> for value in howMany(aDict):
> count += 1
> return count
>
>howMany(x)
>Just wondering why I would be getting that error.
I will show you how I would change the howMany function so that it
prints (to STDERR) its argument(s). This is always a useful
diagnostic or debugging feature. Even after many years, I still
grab frequently for printing variable contents or logging them.
N.B. I'm going to assume you are using Python3.
import sys
def howMany(aDict):
print('%r' % (aDict,), file=sys.stderr)
count = 0
for value in howMany(aDict):
count += 1
return count
This will print out a whole bunch of ['aardvark'], once each time
the howMany function is called. Now, Im going to separate my reply
into one part about recursion and another part about what I think
you are trying to do. First, it looks like you want to see how many
animals have names which start with a specific letter.
You start by creating a dictionary that uses an initial letter as
the key and a list to hold the names of the animals. Your function
could probably be as simple as:
def howMany(aList):
return len(aList)
Note that the object passed into the howMany function is not a dict,
so I changed the variable name to aList. Since I know that you are
trying to learn recursion, then, we could try to use a recursion
solution to your question, rather than use len(aList). It is
important to recognize that the next step is not efficient use of
CPU nor memory, but it should help you play with recursion.
So, now, I'll mention a thing or two about recursion and then I'll
return to your problem about counting the number of animals in each
list, where there's a dictionary key for the initial letter of the
name we give to each type of animal.
One of the most important parts of recursion is defining the
termination condition for the recursion. When does the recursion
stop? When did we reach the end of the list?
One other important piece of successful recursion is to make sure
when you are about to call the function again, that you have changed
something about the variable you are giving to the function. Your
problem, in essence is that you were calling the function like this:
def func(x):
func(x)
There is no difference between what the function accepts and what
the function calls. This, essentially is an infinite loop. And,
Python dutifully runs this until it runs out of stack space. In
Python this sort of error is called an Exception, and it looks like
this:
RuntimeError: maximum recursion depth exceeded
If you look back at your code, you'll also see that Python never
gets to the line where you set count += 1.
So, to review, here's what a recursive function would need to do in
order to count the items of the list:
* have a beginning count of 0
* return the count as soon as it receives an empty list
* strip off one item of the list
AND
* add one to the count, for each time it calls itself
Here is an inefficient function that demonstrates these principles
of recursion:
def howMany(l, count=0):
if not l: # -- termination condition, empty list!
return count
return howMany(l[1:], count+1)
The problems with this list include that it will fail if the lists
are long. For example, I was able to determine that on my box, I can
only handle 988 calls to the same function before triggering the
maxmimum recursion depth exceeded error.
Given that your question was recursion, I chose to focus on that,
but I would recommend using the simplest tool for the job, and in
this case that would be the builtin function called 'len'.
But, this is a great place to ask the question you asked.
Best of luck and I hope you are enjoying Python,
-Martin
--
Martin A. Brown
http://linux-ip.net/
More information about the Tutor
mailing list