修改循环中for循环的迭代列表

2024-03-29 12:07:11 发布

您现在位置:Python中文网/ 问答频道 /正文

for循环遍历一个长列表。我试图加快迭代修改列表(没有成功)。 代码:

from math import sqrt
def holeofStrainer():
    isPrime = [False, False] + [True]*999999
    for num in range(3, len(isPrime)):
        if isPrime[num] == False:
            continue
        else:
            for x in range(2, int(sqrt(num)) + 1):
                if num % x == 0:
                    isPrime[num] = False        
                    break
            else:          
                isPrime[num] = True       
                for item in range (2, int(1000001/num) + 2):
                    ple = item * num
                    if ple < len(isPrime):
                        isPrime[ple] = False  
    return(isPrime) 
print(holeofStrainer())

第5行的目标是避免不必要的计算。你知道吗

第14-17行中,我做了修改(在Eratosthenes筛选之后,我将素数的倍数值改为False),这样就避免了通过第5行进行更多的计算。你知道吗

摘要:

  1. 是否可以从循环本身修改循环迭代列表?你知道吗
  2. 如果答案是肯定的,为什么在我的代码中不好呢?你知道吗

Tags: 代码infalsetrue列表forlenif
1条回答
网友
1楼 · 发布于 2024-03-29 12:07:11

我敢肯定,您遇到了一个过早优化的例子,即尝试在没有先运行代码的情况下构建快速代码。你知道吗

你的外循环

for num in isPrime:

isPrime中的TrueFalse值进行迭代,而不是对数字或索引位置进行迭代。你知道吗

            for item in range (2, int(1000001/num) + 2):
                ple = item * num
                if ple < len(isPrime):
                    isPrime[ple] = False 

正如padraiccunningham在评论中指出的,我不知道这部分代码应该实现什么。还有一个干违规(复制限制数字)。你知道吗

如果我把这些都清理干净,我最终会得到

def holeofStrainer(nprimes):
    isPrime = [False, False] + [True] * (nprimes - 1)
    for num in (num for num, numIsPrime in enumerate(isPrime) if numIsPrime):                                            
        for x in xrange(2, int(sqrt(num)) + 1):                                                                           
            if num % x == 0:                 
                isPrime[num] = False
                break                      
     return isPrime

注意使用xrange()而不是range()。如果这是python2,range()在调用时会创建一个完整的列表,对于较大的数字来说,这会造成很大的伤害。你知道吗

holeofStrainer(1000000)在这里运行大约需要14秒。这可能可以更快地完成(例如,首先只检查并存储奇数),但是已经有了工作版本,因此速度更快。你知道吗

相关问题 更多 >