对于ProjectEuler上的任务,我编写的代码使用强力来查找低于100的最长的素数链,这些素数加起来为素数,代码确实给出了正确的结果。因此对于低于100的数字,答案是2 + 3 + 5 + 7 + 11 + 13 = 41
import math
def prime(n):
for x in xrange(2,int(math.sqrt(n)+1)):
if n%x == 0:
return False
return True
primes = []
for x in xrange(2,100):
if prime(x):
primes += [x]
record = 0
i = 0
for num in primes:
i += 1
chain = [num]
for secnum in xrange(i,len(primes)-1):
chain += [primes[secnum]]
if len(chain) > record and sum(chain) in primes:
record = len(chain)
seq = chain
print seq
print seq
当我运行此代码时,我得到了
[2, 3]
[2, 3, 5, 7]
[2, 3, 5, 7, 11, 13]
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89]
最后一行对我来说非常困惑。在我看来,两个印刷语句应该给出相同的结果。我的变量seq是如何分配给那个长列表的?最后一个列表甚至不满足分配了seq的if语句的要求。我敢肯定这是一些非常愚蠢的脑屁,但我无法弄清楚我搞砸了什么
答案 0 :(得分:7)
seq = chain
为同一个chain
列表创建另一个引用。然后打印该列表,但循环不会停止。
您继续展开chain
,由于seq
只是对该列表的引用,因此一旦循环结束,您就会看到这些更改。在剩余的for
循环迭代期间chain
/ seq
继续更改,但if
条件不再符合,因此您不会看到这些更改发生。
您继续在此展开chain
:
chain += [primes[secnum]]
这使用augmented assignment;它不会创建新列表但会扩展现有列表。它相当于chain.extend(primes[secnum])
。
您可以通过创建chain
的副本来存储seq
来解决此问题:
seq = chain[:]
答案 1 :(得分:1)
在python中,您可以使用+运算符将两个列表连接在一起。 所以[1] + [2]将产生[1,2]
chain += [primes[secnum]]
if len(chain) > record and sum(chain) in primes:
record = len(chain)
seq = chain
print seq
链变量越来越大+ +运算符将链(列表)连接到另一个列表。所以它会变大,当你打印seq时,因为seq现在等于链,你会得到最新的结果。