Python 正在打印给定范围内的所有素数,算法太慢。。如何改进?(代码挑战) 这是一个关于代码挑战的问题,请不要提供太多代码。。我想自己尽可能地解决这个问题。

Python 正在打印给定范围内的所有素数,算法太慢。。如何改进?(代码挑战) 这是一个关于代码挑战的问题,请不要提供太多代码。。我想自己尽可能地解决这个问题。,python,performance,primes,Python,Performance,Primes,我最近开始接触代码挑战,并将其与学习Python结合起来(我每天都是前端javascript开发人员;)。到目前为止一切进展顺利,我确信这是学习一门新语言的最好方法(至少对我来说) 我目前面临一个挑战,要求我打印给定范围内的所有素数,这都是由简单的Stdin和Stdout完成的 到目前为止,我已经尝试了两种方法,都有效,但速度太慢。。下面是我迄今为止最快实现的链接和代码。也许我遗漏了一些非常明显的东西,导致我的python脚本速度减慢。目前,单个测试用例的范围为11000 (您也可以在此处调试脚

我最近开始接触代码挑战,并将其与学习Python结合起来(我每天都是前端javascript开发人员;)。到目前为止一切进展顺利,我确信这是学习一门新语言的最好方法(至少对我来说)

我目前面临一个挑战,要求我打印给定范围内的所有素数,这都是由简单的Stdin和Stdout完成的

到目前为止,我已经尝试了两种方法,都有效,但速度太慢。。下面是我迄今为止最快实现的链接和代码。也许我遗漏了一些非常明显的东西,导致我的python脚本速度减慢。目前,单个测试用例的范围为
11000

(您也可以在此处调试脚本)

“任务/挑战”的描述如下:

输入


输入以单行中测试用例的数量t开始(在接下来的t行中,有两个数字m和n(1将列表理解更改为生成器),脚本将运行得更快

for number in range(max(low, 2), high+1):
    if is_prime(number):
        yield number

将列表理解更改为生成器,脚本将运行得更快

for number in range(max(low, 2), high+1):
    if is_prime(number):
        yield number

将列表理解更改为生成器,脚本将运行得更快

for number in range(max(low, 2), high+1):
    if is_prime(number):
        yield number

将列表理解更改为生成器,脚本将运行得更快

for number in range(max(low, 2), high+1):
    if is_prime(number):
        yield number
(一)它可能由控制台IO控制,打印输出。我更改了输出,因此它使用生成器收集素数,将数字转换为字符串,并用换行符连接数字。这应该可以在列表构建中节省一些内存,并将一些Python列表迭代向下推到Python运行时。这使它在不科学的情况下加快了约30%shed在我的PC上进行测试,对ideone没有太大影响(这可能是因为我预感它在Python2中运行,Python2有一些非常不同的迭代/列表/生成器工作,但在ideone上使用了Python3)

2) 每次运行
if number==2:returntrue
测试;在前10万个数字中,大多数不是2个。在打印其余的素数之前,我提取了它来打印2。很小的改变,不值得

3) 你的范围倒计时-
范围(ceil(初始分隔符),1,-1)
-这真的很奇怪。一个数字被3除的可能性比被19除的可能性要大得多。每三个数除以3,只有每十九个数除以19。因此,为了快速返回函数,请先尝试使用小的分隔符,对吗?我把它设置为计数。速度明显提高,我希望它仍然有效

这大约是原始运行时的50%,在一个偶然和完全不可压缩的情况下。代码现在如下所示:

from sys import stdin
from math import sqrt, ceil

next(stdin) # skip unecessary line

def is_prime(number):
    initial_divider = sqrt(number)

    if number % 2 == 0 or int(initial_divider) == initial_divider:
      return False

    for divider in range(2, ceil(initial_divider)+1):
        if number % divider == 0:
            return False

    return True

for line in stdin:
    low, high = [int(x) for x in line.split(' ')]
    primes = '\n'.join(str(number) for number
                     in range(max(low, 3), high+1)
                     if is_prime(number))

    if low <= 2: print(2)
    print (primes)
    print('')
从系统导入标准输入
来自数学导入sqrt,ceil
下一步(标准输入)#跳过不必要的行
def是_素数(数字):
初始分割线=sqrt(编号)
如果数字%2==0或int(初始除法器)==初始除法器:
返回错误
对于范围内的分隔器(2,ceil(初始分隔器)+1):
如果数字%divider==0:
返回错误
返回真值
对于标准DIN中的行:
低,高=[int(x)表示行中的x。拆分(“”)]
素数='\n'.连接(str(number)表示数字
范围内(最大值(低,3),高+1)
if是_素数(数))
如果低1),它可能由控制台IO控制,打印输出。我更改了输出,因此它使用生成器收集素数,将数字转换为字符串,并用换行符连接数字。这将在列表构建中节省一些内存,并将一些Python列表迭代向下推到Python运行时中。这使得在我的电脑上进行不科学的仓促测试的速度提高了约30%,但在ideone上没有多大区别。(这可能是因为我预感它将在Python2中运行,Python2具有一些非常不同的迭代/列表/生成器工作方式,但在ideone上使用了Python3)

2) 每次运行
if number==2:returntrue
测试;在前10万个数字中,大多数不是2个。在打印其余的素数之前,我提取了它来打印2。很小的改变,不值得

3) 你的范围倒计时-
范围(ceil(初始分隔符),1,-1)
-这真的很奇怪。一个数字被3除的可能性比被19除的可能性要大得多。每三个数除以3,只有每十九个数除以19。因此,为了快速返回函数,请先尝试使用小的分隔符,对吗?我把它设置为计数。速度明显提高,我希望它仍然有效

这大约是原始运行时的50%,在一个偶然和完全不可压缩的情况下。代码现在如下所示:

from sys import stdin
from math import sqrt, ceil

next(stdin) # skip unecessary line

def is_prime(number):
    initial_divider = sqrt(number)

    if number % 2 == 0 or int(initial_divider) == initial_divider:
      return False

    for divider in range(2, ceil(initial_divider)+1):
        if number % divider == 0:
            return False

    return True

for line in stdin:
    low, high = [int(x) for x in line.split(' ')]
    primes = '\n'.join(str(number) for number
                     in range(max(low, 3), high+1)
                     if is_prime(number))

    if low <= 2: print(2)
    print (primes)
    print('')
从系统导入标准输入
来自数学导入sqrt,ceil
下一步(标准输入)#跳过不必要的行
def是_素数(数字):
初始分割线=sqrt(编号)
如果数字%2==0或int(初始除法器)==初始除法器:
返回错误
对于范围内的分隔器(2,ceil(初始分隔器)+1):
如果数字%divider==0:
返回错误
返回真值
对于标准DIN中的行:
低,高=[int(x)表示行中的x。拆分(“”)]
素数='\n'.连接(str(number)表示数字
范围内(最大值(低,3),高+1)
if是_素数(数))
如果低1),它可能由控制台IO控制,打印输出。我更改了输出,因此它使用生成器收集素数,将数字转换为字符串,并用换行符连接数字。这将在列表构建中节省一些内存,并将一些Python列表迭代向下推到Python运行时中。这使得在我的电脑上进行不科学的仓促测试的速度提高了约30%,但在ideone上没有多大区别。(这可能是因为我预感它将在Python2中运行,Python2具有一些非常不同的迭代/列表/生成器工作方式,但在ideone上使用了Python3)

2) 如果number==2,则运行
import math
number=1
count = 0



while(count<10000):
    isprime=1
    number+=1
    for j in range(2,int(math.sqrt(number))+1):
        if(number%j==0):
            isprime=0   
            break
    if(isprime==1):
        print(number,end=" ")
        count+=1    
print("\nCount "+str(count))