Python递归范围问题

时间:2014-01-10 17:01:45

标签: python recursion scope

昨天,我制作了一个Eratosthenes筛子来生成素数并且遇到了一些我无法弄清楚的奇怪现象。

我原来的代码看起来像这样:

def generate(n, p=2, primes=[2], composites=set()):
    numbers = [i for i in range(p + 1, n + 1) if i % 2 != 0]
    composites = composites.union({p * i for i in range(p ** 2, n)})
    for i in numbers:
        if i > p and i not in composites:
            primes.append(i)
            return generate(n, i, primes, composites)
    else:
        return primes

但是,通过连续调用,会发生这种情况:

>>> generate(5)
[2, 3, 5]
>>> generate(5)
[2, 3, 5, 3, 5]
>>> generate(5)
[2, 3, 5, 3, 5, 3, 5]
>>> generate(5)
[2, 3, 5, 3, 5, 3, 5, 3, 5]

所以每次通话都会增加[3,5]。在连续调用generate函数之后,似乎'primes'列表在范围内。

我通过在函数递归时传递列表的副本来修复它。

    if i > p and i not in composites:
        return generate(n, i, primes + [i], composites)

有人知道这里发生了什么吗?

1 个答案:

答案 0 :(得分:1)

因为你通过函数参数传递它,每个函数的独立范围指向相同的数据。变异其中一个变异在任何地方。