When I run the python code below,
def main():
#print prime_factors(10)
print prime_factors(9)
def prime_factors(n, i=2, factors=[]):
if n==1:
return factors
if(n%i==0):
factors.append(i)
n = n/i
return prime_factors(n, i, factors)
else:
return prime_factors(n, i+1, factors)
if __name__ == '__main__':
main()
it returns the expected results, it returns the prime factors of 9:
[3, 3]
If I remove the comment from line 2 "print prime_factors(10)", something strange happens. For 10 everything is fine, but for 9 it does not only contain the prime factors of 9, but those of 10, as well:
[2, 5]
[2, 5, 3, 3]
If I call the function with the two optional arguments
def main():
print prime_factors(10, i=2, factors[])
print prime_factors(9, i=2, factors[])
everything works fine.
[2,5]
[3,3]
I can't figure out why. I suspect this is some issue with scopes, but I just don't understand it :-( Any help would be appreciated.
The default values defined for function arguments are "sticky" - they belong to the function body itself, so when you modify them they stay modified for the next call.
This is because factors
is a mutable default argument. A new list called factors
is evaluated only once, and hence if you mutate the list, you get the mutated list in the succeeding calls. See the following snippet -
>>> def test(a = []):
a.append('x')
return a
>>> test()
['x']
>>> test()
['x', 'x']
Try initializing it's default to None
and then checking on None
and assigning an empty list within the function body.
>>> def test(a = None):
if a is None:
a = []
a.append('x')
return a
>>> test()
['x']
>>> test()
['x']
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With