# [Tutor] Question on lists

**David Ascher
**
da@ski.org

*Thu, 18 Mar 1999 13:23:56 -0800 (Pacific Standard Time)*

On Thu, 18 Mar 1999, Martijn Faassen wrote:
>* Here's the improved function:
*>*
*>* from math import floor, sqrt
*>*
*>* def factor(n, a = []): # if no second argument is passed, use the
*>* 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
*
Martijn should know better than to use an empty list as a default argument
-- he was probably not awake when he wrote that. Try calling factor(36) a
few times and look at the results:
>>>* factor(36)
*[2, 2, 3]
>>>* factor(36)
*[2, 2, 3, 2, 2, 3]
>>>* factor(36)
*[2, 2, 3, 2, 2, 3, 2, 2, 3]
>>>* factor(36)
*[2, 2, 3, 2, 2, 3, 2, 2, 3, 2, 2, 3]
That's because of the famous 'mutable default argument problem', discussed
in the FAQ Question 6.25 http://www.python.org/doc/FAQ.html#6.25.
The solution is to use None and do a test in the body of the function:
def factor(n, a = None):
if a is None: a = []
k = floor(sqrt(n))
for i in range(2, k+1):
if n%i == 0:
a.append(i)
factor(n/i, a)
break
return a
>>>* factor(36)
*[2, 2, 3]
>>>* factor(36)
*[2, 2, 3]
>>>* factor(36)
*[2, 2, 3]
>>>* factor(36)
*[2, 2, 3]
Note that the code *still* doesn't work (it's missing a 3), but I'll leave
that one to others. =)
--david