2017-08-10 73 views
0

我正在練習列表解析和嵌套列表解析。作爲我的練習的一部分,我寫出了等價的循環。這for循環我不能正確,我相信這是因爲我試圖在函數調用中分配一個值而不是一個變量。我收到的錯誤是:For循環,SyntaxError:不能分配給函數調用

File "<stdin>", line 4 
SyntaxError: can't assign to function call 

我已經爲這個循環編寫的代碼是:

import math 

def squared_primes(): 
    list = [] 
    for x in range(1,1000000): 
     for q in range(2,math.sqrt(x)+1): 
      if all(x % q != 0): 
       list.append(x**2) 
    print(list) 

該函數試圖創建完美的正方形,其根源是範圍爲1質數列表到1000000.

有人可以幫助我理解我的循環的語法究竟在哪裏崩潰?另外,我可以做這個嵌套列表理解嗎?顯然,我的列表理解正在破裂,因爲我無法讓我的for循環語法正確...

解決方案:感謝用戶@Evan,我能夠修復變量和語法問題,並瞭解如何修復this thread中的'all()'聲明。

此代碼將正確地從1,1000返回平方素數的列表:

def squared_primes(): 
    list1 = [] 
    for x in range(1,1000): 
     if all(x%q !=0 for q in range(2,int(math.sqrt(x)+1))): 
      list1.append(x**2) 
    print(list1) 
+0

你的意思是將float作爲第二個參數傳遞給range()內建的嗎? – Evan

+0

@Evan不,我的意思是傳遞一個整數。我嘗試把int(q)放在範圍內......但它仍然不會運行。雖然也許我應該留下它,因爲它看起來不像是錯誤。儘管如此,我會再試一次。 – Hanzy

+0

另外,我假設你已經在你的代碼中縮進了squared_primes()函數,但是在這裏發佈時忘了添加額外的四個空格。我可以在沒有函數調用錯誤的情況下運行你的代碼,但如果我刪除了縮進,我顯然會得到缺少縮進的語法錯誤。我用int()類型化math.sqrt(x)+1表達式以再次測試以避免類型錯誤。 – Evan

回答

0

This code will properly return a list of the squared primes from 1,1000:

只不過它返回1作爲列表的第一個元素和1的平方根是不是素數。讓我們來解決這個故障並重寫代碼的正常功能:

from math import sqrt 

def squared_primes(maximum): 
    primes = [] 

    for number in range(2, maximum): 
     if all(number % divisor != 0 for divisor in range(2, int(sqrt(number)) + 1)): 
      primes.append(number ** 2) 
    return primes 

print(squared_primes(1000)) 

順便說一句,這不是列表理解:

all(x % q !=0 for q in range(2, int(math.sqrt(x) + 1))) 

這是一個發電機!如果你想你會做一個列表理解:

all([x % q !=0 for q in range(2, int(math.sqrt(x) + 1))]) 

但與發電機堅持,因爲它失敗的複合材料以較少的努力。

當我們要求一個高達1000000(百萬)或更多的正方形列表時,您的代碼將開始停滯不前。這時候,我們會想要一個更高效的基於篩狀的算法:

def squared_primes(maximum): 
    sieve = [True] * maximum 

    if maximum > 0: 
     sieve[0] = False # zero is not a prime 
     if maximum > 1: 
      sieve[1] = False # one is not a prime 

    for index in range(2, int(maximum ** 0.5) + 1): 
     if sieve[index]: 
      prime = index 
      for multiple in range(prime + prime, maximum, prime): 
       sieve[multiple] = False 

    return [index * index for index in range(maximum) if sieve[index]] 

大約在100,該代碼將返回約20倍比你的基於除法的解決方案更快的結果。

而@埃文光榮理解,因爲它缺乏你math.sqrt()優化,將幅度慢於任一(我仍然在等待它完成一百萬),並開始有兩個不正確的結果列表中的命令。我們可以把它相提並論時,明智的您的修改後的代碼做:

from math import sqrt 

def squared_primes(maximum): 
    return [number ** 2 for number in range(2, maximum) if all(number % divisor for divisor in range(2, int(sqrt(number)) + 1))] 

print(squared_primes(1000)) 

列表理解。但是,再次,錯誤的方法回頭看看基於篩選的實現。

+0

哎呀,謝謝你的支持。我有點粗心,看到1是列表中的第一個元素,但你是對的 - 這不是素數。接得好! – Hanzy

+0

我只是看着篩選算法,我打算看看這個解決方案,這看起來非常有效。我最初確實要求我的代碼中的整數高達1000000,並且注意到花了一些時間... – Hanzy

+0

我正在查看篩選算法(我去了解外部資源以瞭解基礎知識),並試圖弄清楚循環。我得到的數字 - =集(...)表示,從第一個倍數開始,以原始素數(2)計算該素數到最大值,然後從原始全集中減去。我沒有得到的是每次迭代中質數如何增加。我看到prime = numbers.pop()從未標記的素數中提取值,但是這不是從堆的頂部拉出來的嗎?它會先彈出2,然後繼續使用while循環的3 b/c? – Hanzy

0

這是非常簡潔。列表理解是光榮的。

def squared_primes(maximum): 
    return([ x**2 for x in range(0,maximum) if all(x % i for i in range(2, x)) ]) 

print(squared_primes(1000000)) 
+0

我已更新代碼以將list變量名稱替換爲list1,並將int(q)傳遞給range函數,但仍然得到相同的錯誤... – Hanzy

+0

傳遞int(q)將不會修復您的問題,因爲q會是內置範圍()生成的整數。您需要對int(math.sqrt(x)+1)進行類型轉換以修復浮點錯誤。你仍然得到分配函數調用錯誤?我仍然很困惑,因爲我從來沒有得到運行你的代碼的錯誤。 – Evan

+0

我仍然得到相同的分配函數調用錯誤,但類型int(math.sqrt(x)+1)似乎已經修復,並且改變變量名稱。謝謝你的幫助! – Hanzy