重复调用时,python函数返回不同的结果

时间:2013-07-09 20:27:25

标签: python

当我运行下面的python代码时,

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()

它返回预期结果,它返回9的素因子:

[3, 3]

如果我从第2行“print prime_factors(10)”中删除注释,就会发生奇怪的事情。 对于10,一切都很好,但对于9,它不仅包含9的素数因子,而且包含10的那些因素:

[2, 5]
[2, 5, 3, 3]

如果我用两个可选参数调用该函数

def main():
    print prime_factors(10, i=2, factors[])
    print prime_factors(9, i=2, factors[])

一切正常。

[2,5]
[3,3]

我无法弄清楚原因。我怀疑这是范围的一些问题,但我只是不明白:-( 任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:6)

为函数参数定义的默认值是“sticky” - 它们属于函数体本身,因此当您修改它们时,它们会保持修改以进行下一次调用。

答案 1 :(得分:3)

这是因为factors是一个可变的默认参数。名为factors的新列表仅评估一次,因此如果您改变列表,则会在后续调用中获得变异列表。请参阅以下代码段 -

>>> def test(a = []):
        a.append('x')
        return a

>>> test()
['x']
>>> test()
['x', 'x']

尝试初始化它的默认值为None,然后检查None并在函数体中指定一个空列表。

>>> def test(a = None):
        if a is None:
            a = []
        a.append('x')
        return a

>>> test()
['x']
>>> test()
['x']

答案 2 :(得分:0)

将因子= []作为函数参数中的默认值不是一个好主意。 Python首次遇到函数定义时,只会对[]表达式进行一次评估。基本上,这意味着您调用prime_factors的所有内容都将使用相同的列表,并且每个调用都会附加自己的值。

例如:

prime_factors(9)
prime_factors(9)
prime_factors(9)

将返回

[3,3,3,3,3,3]

答案 3 :(得分:0)

请参阅此问题:"Least Astonishment" and the Mutable Default Argument

你想做类似的事情:

...
def prime_factors(n, i=2, factors=None):
    if factors is None:
        factors = [] 
    ...