2016-01-20 75 views
4

對於ProjectEuler上的任務,我編寫了一些代碼,它使用蠻力來查找100以下最長的素數鏈,這些素數加起來就是一個素數,代碼確實給出了正確的結果。因此,對於低於100的數字,答案是2 + 3 + 5 + 7 + 11 + 13 = 41關於變量賦值(Python)的困惑

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語句的要求。我敢肯定,這是一些非常愚蠢的大腦放屁,但我不能找出我搞砸了

回答

7

seq = chain創建另一個參考相同的chain列表。然後您打印該列表,但循環不停止

您繼續擴大chain,並且由於seq只是對該列表的引用,所以一旦循環結束,您將看到這些更改。在剩餘的for循環迭代期間,chain/seq會繼續更改,但不再滿足if條件,因此您不會看到這些更改發生。

您在這裏繼續擴大chain

chain += [primes[secnum]] 

它使用augmented assignment;它不會創建新的列表,但會擴展現有的列表。它相當於chain.extend(primes[secnum])

您可以通過創建一個複製seq存儲chain的解決這個問題:

seq = chain[:] 
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現在等於鏈,你會得到最新的結果。

+0

你的解釋只有意義,因爲我已經知道答案。它根本不是很清楚。 –