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

时间:2015-05-09 21:29:49

标签: python list loops iteration self-modifying

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

add_mutually_exclusive_group

第5行的作用是保留不必要的计算

第14-17行中我做了修改(在Eratosthenes的筛子之后,我将素数的倍数的值更改为False)允许备用通过第5行进行更多计算。

概要

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

2 个答案:

答案 0 :(得分:1)

我很确定,你偶然发现了一个过早优化的情况,即尝试在没有工作代码的情况下构建快速代码。

你的外围循环

for num in isPrime:

迭代True中的FalseisPrime值,而不是数字或索引位置。

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

正如Padraic Cunningham的评论中所指出的,我不知道这部分代码应该实现什么。还有DRY违规(重复限制号码)。

如果我清理所有这些,我最终会得到像

这样的东西
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()。如果这是python 2,range()会在调用时创建一个完整的列表,这对于较大的数字会造成很大的伤害。

holeofStrainer(1000000)需要大约14秒才能在这里跑来跑去。这可能可以更快地完成(例如,通过首先检查和存储奇数),但是SO上已经有更快的工作版本。

答案 1 :(得分:0)

我冒了一个小答案

    def kevara(n):
    marked = [False, False] + [True] * (n - 1)
    for p in range(2, n + 1):
        for i in range(p, int(n / p) + 1):
            marked[p*i] = False
    return marked
isPrime = kevara(1000000)
print(isPrime)

修改迭代循环的问题与此无关。我想一个方法开始于项目&#34; False&#34;,并在列表中迭代候选人的素数,我们将从这个列表中删除先例的倍数。