# [Tutor] Question on lists

**Martijn Faassen
**
M.Faassen@vet.uu.nl

*Thu, 18 Mar 1999 17:47:59 +0100*

Jon Cosby wrote:
[snip question]
>* # Factor by trial division:
*>* def factor(n):
*>* a = [] # Is there a better way to define a?
*>* k = floor(sqrt(n))
*>* for i in range(2, k+1):
*>* if n%i == 0:
*>* a.insert(len(a), i)
*>* factor(n/i) # Factor quotient
*>* break
*>* return a
*
Hullo,
This is a common phenomenon with recursive functions. In your function
you initialize a to a new empty list each time factor() gets called.
Instead, you need to pass the list that you are building along each time
you call the function. The usual Python trick for this is to use default
arguments to functions. This way you can pass the list on to each
recursive function, and the function still works as expected if you use
it with a single argument.
Here's the improved function:
from math import floor, sqrt
def factor(n, a = []): # if no second argument is passed, use the
empty list for a
k = floor(sqrt(n))
for i in range(2, k+1):
if n%i == 0:
a.append(i) # more efficient and readable than
a.insert(len(a), i)
factor(n/i, a) # Factor quotient
break
return a
print factor(36) # test things
Note that there is still an algorithmic problem with your function; the
last quotient doesn't appear to be added to the list (k becomes smaller
than 2, namely 1, so the range command generates an empty list
(effectively nothing). The condition that ends the recursion appears to
be wrong (in your program it occurs whenever k <= 2).
If this one of your first experiences with recursion, welcome to
recursion, that mystical powerful way to program (though it isn't too
fast in Python - go to functional programming languages such as lisp for
that). Do amazing things by just letting functions call themselves; it's
almost something for nothing! At least so it seemed to me at my first
brush with recursion.
Regards and good luck,
Martijn