昨天,我制作了一个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)
有人知道这里发生了什么吗?
答案 0 :(得分:1)
因为你通过函数参数传递它,每个函数的独立范围指向相同的数据。变异其中一个变异在任何地方。