2017-08-10 59 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