# [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

```