Python 3-迭代时从列表中删除元素(Eratosthenes筛子)

时间:2018-08-31 19:31:14

标签: python primes

我正在构建一个程序,使用python使用Eratosthenes筛子的算法来查找所有小于n的素数。 该算法首先创建一个2到n的数字列表,然后在该列表上进行迭代,以删除可用的第一个元素和相应的倍数。问题是我这样做似乎没有得到正确的结果。我也很感谢任何改进性能的建议。

这是算法:

Then

(已解决)这是我的更改方式:

def primes(max):
    '''The sieve of Eratosthenes
    Algorithm to find all primes smaller than max'''
    init = time.clock()
    allNum = [a for a in range(2, max+1)]
    primes = []
    for n in allNum:
        # remove all multiples of prime n
        toRemove = (a for a in range(n, max+1, n) if a in allNum)
        for i in toRemove:
            print('toRemove:', i)
            allNum.remove(i)
        # add the prime to the list
        primes.append(n)

    deltaT = time.clock() - init
    print('Time taken to process:', deltaT)
    return primes

3 个答案:

答案 0 :(得分:1)

一种更快的选择是建立一个布尔值列表(全部为True),并使用算法将它们设置为False。质数是列表中所有保留为true的索引:

def primes(max):
    mask = [True for i in range(0,max + 1)]
    for num in range(2,max):
        if not mask[num]:
            continue
        for multiple in range(num*2, max+1, num):
            mask[multiple] = False
    primes = [i for i,mask_value in enumerate(mask) if mask_value]
    return primes[2:]

答案 1 :(得分:0)

遍历列表时,将引用每个偏移量,而不是每个值。例如,当您获得第一个结果时,如果它符合条件并删除该值,则所有后续值都将向前滑动,并且偏移量将递增。您的偏移量现在是索引1(以0为底)。但是您只是删除了索引0,一切都向前滑了。您基本上跳过了第二个数字。

0$ python3
Python 3.4.8 (default, Mar 23 2018, 10:04:27)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> [a for a in range(1, 20)]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> the_list = [a for a in range(1, 20)]
>>> for a in the_list:
...     the_list.remove(a)
...
>>> the_list
[2, 4, 6, 8, 10, 12, 14, 16, 18]
>>>

答案 2 :(得分:-1)

我不认为您可以在迭代列表时更改列表。

您可以切换到while循环,只要原始列表中保留任何数字,该循环就会运行。对于每次迭代,至少要删除第一个数字:如果为质数,则将其移至质数列表;如果不是质数,则将其及其所有倍数删除。